Yet another Vim tips post
I've been using vim as my texteditor/codeeditor/ide/etc for about 2 years now. Since then, I tried a lot of different plugins, configurations, and end up with a good set for my workflow. I decided to share here some of those, maybe someone will find them useful
First, here's a list of my most useful plugins and some configurations I've done to them:
Command-T is by far my most useful plugin. It searches for files, recursively from the work directory (the place where you opened (g)vim) in a fuzzy way. You call it's search function and start typing the file pattern.
You can also use it to search for opened buffers in the same fuzzy way. And here is some options I've put on my ~/.vimrc:
" This will flush command-T and remake it's cache nmap <C-F7> :CommandTFlush<CR> " This will open the command-t fuzzy search window for files nmap <silent> <Leader><Space>f :CommandT<CR> " This will open the command-t fuzzy search window for buffers nmap <silent> <Leader><Space>b :CommandTBuffer<CR> |
Indexer makes it very easy to automatically generate (and maintain) tags for your projects, so you can jump to them using CTRL+], g+] or even CTRL+Click. All you have to do is install it and it's dependencies (see the homepage) and do a simple configuration.
There is tree ways of configuring it. One is by using it as an extension to project.tar.gz plugin. Another way is by creating a .vimprj folder inside your project's folder, so as soon as it finds that folder, it'll understand that that's a projects' folder and create tags inside that .vimprj. The last one, the one I use, is to create a ~/.indexer_files file and specify a projects parent folder. That way is perfect for people who keeps all of their projects inside the same directory, and it supports nested directories. Here is my configuration as an example:
[PROJECTS_PARENT]
~/dev/
~/dev/external/
~/dev/stoq/
~/dev/icmc/
~/dev/proj/ |
By doing that, the tags will be generated/updated at a folder ~/.vim_indexer_tags. It's so simple that I never have to remember to generate/update tags for none of my projects, even one that I just created (since they will be on one of PROJECTS_PARENT directories).
That's another very useful plugin for people who uses grep a lot. It grep for a pattern, and populate vim's quickfix window with all the found patterns, so it's easy to access them, so you can navigate through them using ]q (the same as :cnext) and [q (the same as :cprev).
And obviously, you can setup some maps to make it easier to grep your pattern. Here is a piece of my ~/.vimrc:
" Files to skip let Grep_Skip_Files='*.bak *~ *.pyc *.o *.obj' " Directories to skip let Grep_Skip_Dirs='.bzr .git .hg' " The grep itself nnoremap <silent> <Leader>gg :Grep<CR> " Grep recursively nnoremap <silent> <Leader>gr :Rgrep<CR> " Grep buffer nnoremap <silent> <Leader>gb :Bgrep<CR> |
Those are just my must-have list. There are some other that I won't detail here but I find useful too, like:
- NERDCommenter plugin: Makes (un)commenting code lines a lot easier.
- buffexplorer plugin: Makes it easier to change opened buffers.
- vcscommand.vim plugin: A lot of useful tools to work with vcs systems (like git, bzr, svn, etc) inside vim.
- indent/python.vim plugin: A better and more PEP-8 version of python indentation.
To finish, here is some general-use pieces of my ~/.vimrc:
" Dictionary and Spell Options set spelllang=en,pt set dictionary+=/usr/share/dict/words " Jump to the last position when the file was last opened.. autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif " Visual help to keep text on 80 columns set textwidth=79 autocmd BufEnter * hi ColorColumn ctermbg=lightred ctermfg=white guibg=#592929 if version >= 703 autocmd BufEnter * set cc=+1 else autocmd BufEnter * match ColorColumn /\%80v.\+/ endif " Clear highlight when refreshing. nnoremap <C-L> :nohls<CR><C-L> inoremap <C-L> <C-O>:nohls<CR> " Make Y compatible with D nnoremap Y y$ " Make Shift+Insert paste from global clipboard nnoremap <S-Insert> "+p inoremap <S-Insert> <C-O>"+p noremap! <S-Insert> <MiddleMouse> " Continous visual indenting vnoremap < <gv vnoremap > >gv |
Most of those tips/plugins were found googling, on vim tips wiki and vim scripts itself.
Suggestions for improving this post are very welcome!
Gnome-shell Notifications Alert Extension
If there is anything that I dislike on gnome-shell are the notifications...wait, not the notifications itself, I really like the whole bottom hot corner concept and stuff. But it's very easy for me, specially at my work that I use dual monitors, to miss an im message that way.
I then started to search for a shell extension that provides something to alert me of the existence of an unread notification. I found the Pidgin Persistent Notification's concept very good and decided to try to do a generic one (since it's pidgin specific). This is the result:
It supports any shell version >= 3.2. You can download it on extensions.gnome at the link: Gnome-Shell Notifications Alert
The source code is on github <https://github.com/hackedbellini/Gnome-Shell-Notifications-Alert> and licensed at GPLv2. Fell free to fork it! Just don't forget to send me a pull request, so I can merge your improvements into the official code ;D
Writing asynchronous Python code with Twisted using inlineCallbacks
A few weeks ago, I started using Twisted for developing a plugin for synchronization between Stoq and Magento.
Twisted is really a great tool, and it makes it very easy to write asynchronous code. The only problem is that your code has a high probability of becoming Spaghetti code
. And anyone who knows me knows that I'm crazy when it comes to code organization.
Well, those days, specially after a hint by a work mate, Johan Dahlin, I started to take a look on inlineCallbacks decorator. It's just beautiful and solve all my problems
.
Since I found the documentation a lot hard to understand, and little examples on the web, I decided to try to make one of my own. Hope you will enjoy!
Now, consider the following piece of code (utilizing the classic Twisted way):
from twisted.internet import reactor def on_failure(err): print "Error:", err reactor.stop() def on_success(*args): print "Success. Shutting down" reactor.stop() def print_file(file_): d = async_print_file(file_) # This will return a Deferred d.addCallback(on_success) d.addErrback(on_failure) def get_file(): d = async_get_file() # This will return a Deferred d.addCallback(print_file) d.addErrback(on_failure) if __name__ == '__main__': get_file() reactor.run() |
On this example, we want to get a file, print it, and then shutdown the application. Yeah, it's ugly, a little spaghetti (could be a lot more if the code wasn't a simple example)...but it works.
Just for a fast explanation, the async_*() functions are fictitious functions that will return a Deferred. When it's fired, it'll call the function added by addCallback, or, in case of failure, the one added by addErrback. If more than one callback (or errback) is added, when the first one returns, that return value will be passed to the second function, and so on, as a chain of callbacks.
Now, take a look at the following piece of code (utilizing the inlineCallbacks way):
from twisted.internet import defer, reactor @defer.inlineCallbacks def print_file(): try: # async_get_file still returns a Deferred file_ = yield async_get_file() # After yield, it's not a Deferred anymore yield async_print_file(file_) print "Success." except Exception as err: print "Error", err finally: print "Shutting down" reactor.stop() if __name__ == '__main__': print_file() reactor.run() |
Beautiful, isn't it? What does all the magic is the yield statement (without using it, file_ would still be a Deferred)
When the code inside a function decorated by the inlineCallbacks decorator yields a Deferred (in that case, a function that returns a Deferred), the code goes on and the reactor will come back after the Deferred fires. It's return value will be returned on the yield statement, and, if any errors occurred, the exception will be raised (that's why I yielded inside a try/except clause).
Note that, because yield is captured by inlineCallbacks, there's no way to use that function as an iterator generator.
And if we need to call another function decorated by inlineCallbacks? How to get it's return value, as the return statement won't work? Well, that's why there is a function called returnValue. Take a look at the following piece of code:
from twisted.internet import defer, reactor @defer.inlineCallbacks def get_arg(): retval = yield another_async_func() defer.returnValue(retval) @defer.inlineCallbacks def print_file(): try: arg = yield get_arg() except Exception as err: arg = None try: file_ = yield async_get_file(arg) yield async_print_file(file_) print "Success." except Exception as err: print "Error", err finally: print "Shutting down" reactor.stop() if __name__ == '__main__': print_file() reactor.run() |
In this example, we assumed that async_get_file neeeded an expecific argument, that needs to be retrieved asynchronous too. By doing returnValue(arg), we make anyone who yields get_arg() to receive arg, or raise an exception if an error occour.
A little complicated but, after a while you get used to it!
Any doughs?
PPA for the latest and greatest Vim
Want to run the latest and greatest Vim on your Ubuntu installation without having to "configure;make;make install" ? Use my Vim PPA: https://launchpad.net/~hackedbellini/+archive/vim
If you don't know how to proceed, take a look at the instructions here: Vim PPA instrictions.
Hope you enjoy!
Update 10/26: If you wish to remove my PPA and return to the official repository version, use ppa-purge.
A simple script to help with simple “Test Cases”
Just here to share a simple script I wrote to help with some test cases on university.
- What it does:
1- It takes all ".in" files it finds recursively on the folder and show how much time your algorithm takes to process each one.
2- For each ".in" file, it tries to find another one with the same name but with the ".out" extension. If it finds, it'll diff both that file and the output of the ".in" file and show if your algorithm is correct. If not, it shows the diff.
- The script:
Download it at: http://gist.github.com/631593. Name it as you wish! (In the explanations bellow I'll assume the default name "TestCases")
- How to use:
You can put the script anywhere and call it using it's absolute/relative path. If you want to call it just by it's name, make sure it's on your $PATH. To do so, add this to the end of your .bashrc:
export PATH="PATH/TO/SCRIPT":"${PATH}"
Make sure the ".in" and ".out" (if any) files are in the same folder (or in a sub-folder) of the executable you will test. Lets suppose the executable is called "EXECUTABLE" and you are on it's working directory...you can run the script like this:
TestCases EXECUTABLE
Watch the output and enjoy! ;D
The script is a Gist, so, if you want to improve the script, fork it! After you made the changes don't forget to tell me so I can pull your changes.
My first tatoo is a Debian tatoo!
I just wanted to share this with you! A photo of my first tatoo! (on my right calf) It's the Debian Swirl.
And yes, I'm that kind of "Linux Addicted". Next ones: Tux and the Glider (Hacker Culture symbol)
Ubuntu 10.10 Maverick Meerkat is out!
Today is the big day! Today is the Perfect 10 day!
Ubuntu 10.10 Maverick Meerkat has been released. You can download it from here: Download Ubuntu (prefer the use of Torrent links. It's better for you and for the community ;D)
If you are already an Ubuntu User and want to upgrade it, press ALT+F2 and type "update-manager -d". The Update Manager will pop-up with a button "Upgrade to 10.10". Just click it and the upgrade will begin! This is the official and the recommended way of doing the upgrade, as you can see here Upgrade Ubuntu and here Help Upgrade Ubuntu.
Take a look too at the Maverick Meerkat Technical Overview.
After doing a fresh install, or upgrading, if you want to have things like Flash, Java, Multimedia Codecs installed, just go to the Software Center and install the "ubuntu-restricted-extras" package.
Also, find the LoCo Team next to you and go celebrate the Ubuntu 10.10 Releasy Party!
Update 10/11/10: Found an excelente article at OMGubuntu about news in 10.10. Take a look: Ubuntu 10.10 News
PPA-Purge: The best friend for people who lives on Bleeding Edge
If you, like me, love to live on Bleeding Edge, probably you have a lot of PPAs added to your Ubuntu's Software Sources. What's the big problem? Unstable stuff can will crash sometimes.
What to do when you want to return a package (or some packages) from the PPA's version to the Ubuntu's official version (wich is considered to be more stable)? A solution could be removing the PPA entry from the sources.list and manually forcing each package to the version you want. Now think..What if a PPA upgraded something like 50 packages on your system? Will you manually downgrade each one? Will you remember all packages that it upgraded? Now comes the best part...you don't have to do that! Just call your best friend, PPA-Purge!
PPA-Purge will remove any PPA you added from your system and downgrade every package it upgraded with only one command.
How to install:
It's on Marverick's official repository and has been backported to Lucid Lynx. To install, just click here or run the following command:
- sudo apt-get install ppa-purge
How to use:
Just run "sudo ppa-purge [the ppa you want to remove]".
Here are some usage examples. These examples bellow are the output of the command "ppa-purge --help"
- sudo ppa-purge xorg-edgers
- will remove https://launchpad.net/~xorg-edgers/+archive/ppa
- sudo ppa-purge -p xorg-testing sarvatt
- will remove https://launchpad.net/~sarvatt/+archive/xorg-testing
- sudo ppa-purge ppa:ubuntu-x-swat/x-updates
- will remove https://launchpad.net/~ubuntu-x-swat/+archive/x-updates
Hope you enjoy it as much as I do! It sometimes can be a life-saver
Ps. The latest version of Ubuntu Tweak has integration with ppa-purge making it even easier to use!
How Hotmail prevented me from getting online on my ICQ account
I know that you are thinking "Hotmail and ICQ? What's the connection between them?"..and, well, let me tell what happened!
I was configuring my IM accounts on Empathy, the default IM client on Ubuntu, when I saw that it supports the ICQ protocol. It has been at least 8 years that I stopped using my ICQ and I decided to login in my account to see what was going on there. Even not using it for a long time, I still remember my ICQ number. The problem came when I tried to remember my password. I was 12 years old when I created it =/
But, ok, it isn't the end of the world. That situation is easy to solve! I just had to use the password recovery system on ICQ page. The only problem: They sent the information of how-to reset my password to the e-mail that was registered in my account. And yes, 8 years ago I was a hotmail user. Do not crucify me! I was a child, didn't know what I was doing =(
Like my ICQ password, I have no idea of what the hell was my hotmail password. The solution, again, was to use the password recovery system on hotmail's page. It asked for my e-mail and a captcha. So, I went with: foo_bar@hotmail.com (I'm not going to show the real alias because it was REALLY stupid! I was 12 =P. Just using "foo_bar" to show the example). What I got after this? That will make you laugh:
"Password reset instructions were sent to: foo_bar@hotmail.com.
If you don't see the e-mail message in your inbox, look for it in your junk mail folder or check your e-mail again later."
FAIL!!!!!
If you can't understand the fail, take a look at the e-mail I was trying to recover the password and the e-mail they sent the password reset instructions....got it? ;D
So, that's how Microsoft and Hotmail developers f***ed with the only way I had to login on my old ICQ account. I'll try other ways and hope to get online soon! If someday I success, the user #176444719 will be online again!!!
FISL11 was Awesome!
The International Free Software Forum (In portuguese "Forum Internacional do Software Livre" - FISL) was great!
It was my first time in a Free Software event and it was really exiting. I met a lot of great people there and saw that the FOSS community is greater and more awesome than I thought. Photos can be founded on my Picasa: Thiago Bellini Picasa Album - FISL. Also, André Noel took a lot of great photos there, which can be founded on his Picasa: Andre Noel Picasa Album - FISL
The next FISL will be FISL12 and will probably happen on July of 2011. But 2010 isn't over yet! Latinoware is coming in November and looks like it will be as awesome as FISL was!
To finish this post, I want to give a special "Thank You" for the guys from the Ubuntu-BR-SP team. It was a pleasure for me to be part of the caravan and I really learned a lot from everyone! You guys are really Great!!! Hope we can keep in touch and improve more our friendship.




