Hacker News new | past | comments | ask | show | jobs | submit login
Vim Git Gutter (github.com/airblade)
371 points by glazskunrukitis on March 5, 2013 | hide | past | favorite | 115 comments




Use https://github.com/syohex/emacs-git-gutter-fringe if you want the symbols in the fringe.

But sadly the Emacs mode calls git synchronously which can lead to a significant slow down when switching buffers. I hope that gets fixed.


Ok, as a challenge, I'm gonna try make a Conception version, brb.


What is Conception? I searched for “conception text editor” and didn’t find anything.

Edit: Found it – it’s https://github.com/shurcooL/Conception, a research project IDE that you’re working on.


All right, I think I'll stop here. Parsing the -U0 ranges in raw C++ is gonna be too much wasted effort. I'll finish this another time, likely after switching to Go.

But I was able to get a rough prototype running.

Screenshot: https://dl.dropbox.com/u/8554242/dmitri/projects/Conception/...


Why are you using C++?


For historical reasons, mainly. If I were starting from scratch today, I wouldn't pick it. I'm in the process of making a change to golang, but I want to use the existing project to develop the next-gen version. There's only a few more things I need to add to make it viable for working on a large-scale project.

I started the project a year ago. I wanted to have the power and flexibility to achieve anything, and use OpenGL for graphics so there'd be no restrictions as to what can be put on screen. Plus I've been using C++ for many years before for making indie games.

Back then, I was even more motivated to work on it because I felt C++ itself badly needed a more efficient way or writing it. I really dislike the manual duplication it forces you to create and maintain as you change things (e.g. cpp and header files). But even with a more script-like high level language like Go, I feel there is a lot of potential to innovate past a basic text editor. I'm gonna find out.


Relatedly, noble cause with your IDE project, here's hoping you run into wonderful things (alas, I can't code C++ and VimL serves me fine for my current extension needs)


Thanks a lot, I'll do my best! :)



aka the original :)


Not to take away from the post, anyone else feeling a bit of Vim overload in the past few days? I'm pretty much Vim'ed out with all the Vim related postings.


I don't really understand what you mean. People submit vim-related content, which then gets upvoted and brought to everyone's attention on Hacker News.

It might just be that it actually reflects people's interests. Given how established vim and emacs are, I have to say I'm not surprised, they remain extremely versatile and complete developing environments to this day.


I actually use Vim. I don't have any issues with it. I do agree with you that it's a great tool.

Just pointing out that lately there has been a lot of Vim related posts that are being up-voted. Maybe that's been the case for a while, and I am just noticing it.

Anyway, my comment was meant more as a light humour rather than critical.


Nope. Anything that makes my development easier is anything but an overload to me.


Probably just due to a lull in the SublimeText posts.


Hey guys, we've got an emacs user over here.


This is really nice, but I wish the background color of the gutter would automatically match the rest of my background. The gray band [1] is pretty unappealing IMO.

Also noteworthy is that that the gutter only updates when the file is saved.

[1] Screenshot: http://imgur.com/TIGKVRS


You can achieve that manually with `highlight clear SignColumn` in your colour scheme or ~/.vimrc.

I'll (I'm the author) probably make this the default because it seems quite a common wish.


Alternatively, using `hi! link SignColumn LineNr` will ensure that styling the user has applied to the more commonly used line numbering column will match the sign column used by vim-gitgutter.


I hate it when plugins try to override my colorscheme, so I would highly discourage adding this to the plugin. To account for colorschemes that don't add colors for SignColumn without angering users, use the `default` keyword without the bang.

Some other things to consider: The sign column and line numbers are separated by the fold column. The default colorscheme has SignColumn and FoldColumn the same (Cyan or DarkBlue on Grey) and different from LineNr (Yellow or Brown).


Sorry, I was mistaken--the sign column is placed between the fold column and the line numbers.


AFAICT, this was technique advice specifically relevant to the parent post, the ongoing thread, and to improving folks experience with the tool in original post. To the anonymous downvoter: I give up. I have no idea what message you were trying to send.


I've added it at the bottom of ~/.vimrc, but for some reason it doesn't work until I explicitly type `highlight clear SignColumn` while editing a document. Any ideas why this could be happening?

Great plugin by the way, super handy.


I had the same problem, I did:

au VimEnter * highlight clear SignColumn


Works like a charm, thanks :)


I had the same problem at first. Try putting it after wherever you're loading the plugin itself.

edit: Also, thanks airblade. I think I'm going to keep using this.


I experimented a bit more and found if I put it before my "syntax on" and color scheme setup lines it doesn't work, but if I put it after them the fix works. Raticide's comment clued me in.


You colour scheme is probably overriding it. You might want to edit your colour scheme's script and add it there.


Try

hi SignColumn ctermbg=232 guibg=#080808


None of the suggestions work for me. Plugin called via Pathogen - could this be an issue?


I'd suggest leaving the highlighting of SignColumn to the user's colorscheme.


I would appreciate this to be the default.

Thanks for your work!


Very cool... I'm going to keep using this!


What colorscheme? Is it just not changing the default colors for the SignColumn group?


I've also got a similar plugin https://bitbucket.org/sirpengi/iwilldiffer that works with hg as well as git. Mine uses python though, nice to see an implementation that's all in viml. Neither of our plugins are async though (so vim ui will block while the diff is running), which is the biggest hurdle I want to cross.


As far as I know Vim is single-threaded; you can't run operations asynchronously.


That's neither here not there. You have plenty of things which are single threaded but allow concurrency (Twisted, NodeJS...). That it does not have an asynchronous API is something different.


Yes, but there is a way to work around that with a ton of hacks (by spawning a separate process, and polling CursorHold events). See https://github.com/troydm/shellasync.vim and a bunch of linting plugins do this too (but I can't remember them off the top of my head).


Or you could, e.g., use the Lua scripting extension, load one of the native threading libraries for Lua (Lua Lanes, for example) and fire away a few background tasks. Whatever actions the background tasks need to perform with the buffers you'd have to serialize, but that shouldn't be all that difficult.


So long as any plugin script is running, vim will block waiting for it. And if you fire off a background process and exit from your main script, any reference to the vim environment within your child process becomes useless, so you can't modify anything in vim from within there anymore. I'm not entirely familiar with the lua scripting extension, but this was my experience attempting the same thing in python. I mean, at the end of it, vim is single threaded, and after your primary script exits its state is being used elsewhere - if you could modify it from your child process that'd be major cause for crashage.

That and who has lua on their system (I mean, i do for Love but that's irrelevant) or wants to install it just to use a git/hg plugin?


For the second part, your plugin is written in Python, so you could use Python instead of Lua.


You'd have to implement a message queue, of course. As for the second part, who hasn't? Many applications are using Lua as we speak.


This is fantastic. Thank you.


Eclipse pretty much does this out of the box. I guess so do IntelliJ and Visual Studio. You can also display the name of the last person to change a line in the same position (ie. svn/git blame), which is very useful to quickly find out who to talk to regarding a section of a file. The commit message is displayed on mouseover.


Yes, IntelliJ handles this pretty nicely. For modified lines, you can mouse over to see what you changed. For all changes, you can click a context menu to revert any given change. (Of course, that does require touching a mouse... though I believe you can set up a key mapping for it.)


Shift+F10 opens the right click menu in most contexts.


And before anyone asks, you can easily access the menu contents with the keyboard.


Netbeans has the same functionality, so I guess it's something that has become "standard" in most IDEs


Using the vim Fugitive you can quickly toggle a git blame sidebar to determine all this similar type of information.


Also gotta love the ability to open commits in Github in IntelliJ and the other JetBrains IDE's. Great for sending a link to a line of code.


vim Fugitive does this as well. `:GBrowse` will open the current file on GitHub, with an optional line range.


It'd be perfect if the signs changed in real-time without the need to save first. Awesome work though. Thanks Andy.


I'll look into that...


+1 that request. Really good plugin otherwise.


Taglist does something similar, and it uses ':h updatetime' to toggle how often it works.


My thoughts exactly, that would be awesome!


That's a lot of "git diff" calls!


In the Sublime version, one of the things I did to avoid that is it doesn't call `git diff` if it has been less then 5 seconds since the last `git diff`.


Or a reimplementation of the algorithm in VimL ;)


The Sublime version does.


Is there any way to make it so that the gutter is always present? There's a bit of a noticeable jump to include it when I save a file, it's sort of annoying me.

I tried

  let g:gitgutter_enabled = 1
but that does seem to work.

I'll have a poke through the source.



probably not, the way vim works if there are no more signs attached to a document the gutter goes away. This isn't plugin related, it's just a manner of how vim works.

Although I suppose you can work around this by displaying a fake sign (color match gutter background?), but that has its downsides (depending on colorscheme, the sign can show up. and vim doesn't support whitespace characters for signs, at least not from what I can see).


Yeah, I just noticed that now.

It seems to just grep through the diff itself, so adding a fake sign would be a pain and, as you mentioned, probably not display correctly anyway.

I'm sure my eyes will adjust :).


Why can't you change it if you want to?


I wish it could be made to stand on the right side of a vim buffer. This way it would still be present on demand but would not shift the whole buffer one column to the right.


Ugh, someone submitted the original Sublime version to hackers news 2 months go http://news.ycombinator.com/item?id=5027308 and it got no love.

It just makes sense that someone would port it and become the #1 story.


Maybe because there are more vim users than sublime users on hn? FWIW i did see that story on front-page of hn and it's what prompted me to immediately write my vim-port. I finished it like a few days after that.


An aside question; what's the deal with "pathogen"?

I've been using the "/bin/cp" command for years installing vim plugins and it's worked remarkably well; requiring just about 1 invocation on average...

What problem does that thing solve?


If you decide you no longer want a particular plugin, or want to upgrade it, it can be hard to tease out the files you /bin/cp'd into place. Adding a single folder under bundle makes removal easier later.

ETA: also note that git-cloning into bundle means that upgrading is just a question of entering the plugin directory and running git pull.


Each plugin resides in it's own directory, rather than being scattered around your .vim dir. Try to remove one of your installed plugins, you'll have to dig around and it'll be messy.

Also it makes it easier to update, since all you need to do is replace the folder with the newer version and you're all set.


To elaborate on the response others have offered about everything being in one folder, I'll further note that it allows you to keep track of the plugin through git, so you can very easily grab updates when desired.


I have 5 separate computers that I run vim on. Manually installing and updating is a huge pain. I keep my .vimrc in git to keep them all synchronized.


I use Vundle to take this a step further

https://github.com/gmarik/vundle


Fantastic plugin.

:BundleUpdate when you've got 20 plugins homes across Github and vim.org is a huge timesaver.


Why git? I store my .vim directory in dropbox and just have it symlinked into my home directory on each of my machines. I don't really see a need for version control, and I don't want to have to do anything to make sure a change on one machine is reflected on all the others.


Why can't you also keep your .vim in git too then? It seems to work well for me. see: https://github.com/kristopolous/vimbuild


Three killer uses:

- removal - git submodules - conditional loading of plugins


It lets you put your various vim things inside a single 'bundle' directory instead of having files in plugin/ftplugin and whatnot. Very convenient and easy to setup.


Seems to add noticeable latency (1+ seconds) to my save, each time. Vim is unresponsive during this time

Is this expected? I save quite frequently, it's an unconscious reflex at this point.


Yes, the plugin runs the diff command when a document is saved/loaded. See the discussion here: http://news.ycombinator.com/item?id=5326654


Figured as much. I would argue for/request forking that "git diff" command and only processing its output in the VIM process, but for the moment I'll stick with my trusty ",gd" command:

  map <leader>gd :!cd %:p:h && GIT_PAGER='' git diff HEAD -- %:t<CR><CR>


Out of curiosity, what is the line count on the file where this is happening?


This works really quite well - great work, airblade! For reference, this is what I placed in my vimrc to get things how I like them:

  highlight clear signcolumn
  let g:gitgutter_enabled = 0
  nmap <leader>gu :GitGutterToggle<CR>

I prefer my buffers to start with it disabled by default and toggle as needed.


I'm really impressed with this -- I would love to see this see functionality for other VCSes (subversion, etc) so that I could use it with my non-git projects. The vimscript looks pretty clean -- maybe I have a new weekend project ahead of me.

edit: just a quick hack for a "vim svn gutter": https://github.com/prg318/vim-gitgutter

The code is really clean and it would be fairly trivial to adopt this for use with any other VCS. Open source yay!


svndiff (http://www.vim.org/scripts/script.php?script_id=1881) works with SVN, Git and others.

Both sign-diff (http://www.vim.org/scripts/script.php?script_id=2712) and changesPlugin (http://www.vim.org/scripts/script.php?script_id=3052) are VCS-agnostic: they show differences between the saved state and the current state.


Thank you! I wasn't aware that these plugins existed already. While I was getting excited to get my "vim -D" on to get the script in the OP to work with svn, I might just work one of these plugins into my workflow.

Thanks!


Here is an idea to keep your forking mojo going: "improve" the looks of svndiff to match the looks of git-gutter.


Any way to bind "toggle the gutter" so I can press my "set nonumber" button and have it toggle the gutter as well? [edit] Apparently I didn't read down far enough! This functionality exists already through the plugin. This works for me: nnoremap <F2> :set nonumber! <bar> ToggleGitGutter<CR>


vim-patchreview is a bit different, but also of interest: https://github.com/vim-scripts/patchreview.vim

I find it really useful in particular for working with Mercurial patch queues. I have a command in my .vimrc that will run ReversePatchReview on the topmost patch in my patch queue. It pops up a diff tab for each file that has changed. I can easily use "[c" and "]c" to jump between changes within each file.

This setup makes it incredibly easy to review the changes a patch makes, and it's so convenient that I often write quite a bit of my code inside these diff views. I don't think I could live without vim-patchreview when working with Mercurial.


If you like gitgutter and you are a fan of textobj plugins you might also find this useful:

https://github.com/gilligan/textobj-gitgutter


This looks amazing. Nice work! Does it always diff with the last commit?


It diffs your working tree with the index (i.e. what a plain git-diff does). I plan to make it easy to `git-diff --cached` too.


There is another implementation, it's a bit faster and well documented :)

And there is more customisable as well

https://github.com/mhinz/vim-signify


Very cool. Pointed me at the Sublime Text version and I love it.



Awesome work! Cheers airblade. One nitpicky thing though, why do you use "_" and not "-" for removed lines? Can't see why you wouldn't want it vertically centered!


Removed lines happen between existing lines, so using an underscore makes it look like that.

Compare:

    25  - def foo():
    26       baz()
With:

    25  _ def foo():
    26       baz()
(Where there used to be a bar() call before baz().) The first version makes it look like the `def foo():` was somehow removed.


Valid point! Can't believe it didn't occur to me ;)


I would love something like this for TextMate 2.


For what it's worth, I installed this in my VIM, switching between files took about 4 seconds instead of 1, so I uninstalled it.


Great stuff, I was using svndiff before this but it was more of a miss than a hit, this seems to work nicely so far.


It works fine, but I am unsure of what advantage it has over svndiff, which also works fine.


Well, in my case svndiff never worked fine, it would showbad diffs 9/10 of the times, but maybe it was just a misconfiguration on my part.


Brilliant, I have been meaning to build this exact same plugin for a while already, thanks a lot for doing this!


Nice! This is one of the things I got used to in RubyMine that I've missed in vim.


Edge case: after deleting the first line, no gutter shows op


often do a "git add -p" and commit different aspects works for me.


I honestly like vim fugitive because of it's awesome power. I just type ,gd to see a diff in a split. I probably don't want to scan the gutter for files i've changed, and fugitive diff folds all non-changed lines

also, who the hell sets their font size that small? (screenshot in the readme). that's a sociopathically small font size. I will never trust you airblade. never.


I use both. If I need a full diff, fugitive is great. Sometimes I just want to scan to see what lines I changed in a a file. In other words, it is impractical to use this plugin to find out what _files_ you've changed. It is great for finding out what lines in whatever file you've opened have changed.


fugitive split diff shows you what lines you've changed. stop using both.


No. You you do your thing. I'll do this. I don't want to have to run another command to see what lines have changed in my file. I want small, non-intrusive icons in the gutter without doing a damned thing.


I honestly prefer vim fugitive's diff function, as it splits with highlighted lines.


Sure, but there's a difference between some nice lil gutter glyphs in the background and a deliberate ':Gdiff' command.

In other words, why not both?




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: