onivim / oni

Oni: Modern Modal Editing - powered by Neovim
https://www.onivim.io
MIT License
11.35k stars 299 forks source link

Git / Version Control Integration #2110

Open bryphe opened 6 years ago

bryphe commented 6 years ago

These are some thoughts on scenarios I'd like to support with version control integration.

Some specific scenarios that are important to enable:

These are primarily common problems across VCS providers. It'd be great if we could generalize these capabilities to work with different VCS providers, and allow a way to implement providers.

The 'provider' could be implemented as an interface - this is just a quick sketch of what a VCS Provider could look like:

export interface VersionControlProvider {

    // Events
    onBranchChanged: IEvent<BranchChangeInfo>
    onFileStatusChanged: IEvent<FileVersionStatus>
    onStagedFilesChanged: IEvent<StagedFilesStatus>

    // Given a workspace path, returns 'true' if the provider can provide
    // version control capabilities. For example, a `GitVersionControlProvider`
    // would look for the presence of a `.git` folder at the root.
    canHandleWorkspace(workspacePath: string): Promise<boolean>

    // Get the 'blame info' for a file - the per-line
    // information about a commit
    getBlame(filePath: string): Promise<FileBlameInfo>

    // Get the history for a file, to allow
    // quickly navigate and diffing commits
    getHistory(filePath: string): Promise<FileHistoryInfo>

    // Get conflict regions for a file. This will be used
    // for a 'buffer layer' so that we can render some
    // custom UI for this.
    getConflictRegions(filePath: string): Promise<ConflictRegionInfo>

    // Change the branch
    changeBranch(branchName: string): Promise<void>

    // Get all available branches
    getBranches(): Promise<string>
}

Then, individual plugins could provide implementations of this. For example, a plugin like oni-plugin-git might have this:

export class GitVersionControlProvider implements Oni.Plugin.VersionControlProvider {
    ....
}

oni.vcs.registerProvider(new GitVersionControlProvider())

In addition, we'd want to add a 'contributes' section to the plugin metadata and a relevant activation event, so that we can 'lazy load' these plugins - we wouldn't need to load the VCS plugin until we've opened a workspace.

(I anticipate that the version control provider would listen to buffer events, like save, so it could use those to decide when it should check VCS status).

Even the relatively simple interface above would let us accomplish a pretty significant subset of functionality!

I think it would make sense to bundle the git integration as a first-class citizen, but allow this API to be open for other version control providers, too.

bryphe commented 6 years ago

Some open issues:

bryphe commented 6 years ago

On top of the interface, there'd be several pieces of UI we could expose:

The nice thing about decoupling the 'interface' from the actual underlying implementation is it makes it easy for us to create a 'Mock' version control provider and ensure the UI works against it - so the work could be parallelized between the 'backend' providers and the UI work.

mg979 commented 6 years ago

Is it (or will it be) possible to have diff popups when hovering the gutter, over diff signs provided by plugins? Sublime Text GitGutter does it:

pic

Vim GitGutter does almost everything right, but the preview needs it own buffer.

badosu commented 6 years ago

@bryphe I very much like Fugitive, it's my favourite plugin, but I am not sure it would interface well to provide visual features. E.G. this is the blame feature :Gblame:

screenshot from 2018-04-18 07-50-34

As you can see it's a separate buffer that would have to be parsed to extract data. Or you would overlay it in some way for when you want to see the blame, the good thing is that it's so complete that if you click on the commit hash you are directed to a new buffer containing the git show for that commit.

It does have some functionalities you require, e.g. you can jump between conflict markers (using unimpaired.vim) with [c and ]c (by populating the error quickfix, :cfirst, :cnext, etc). And it should be pretty easy to hook up functionalities to it's commands: Gwrite, Gread, Gdiff, Glog, etc...

For managing the index, Gstatus is amazing, it has a pretty easy to use interface with many shortcuts implemented. I might use it maybe 30 times a day..

You can, for example, navigate with the cursor to an index entry and hit a shortcut:

screenshot from 2018-04-18 08-03-37

As I said, since it had to interface with normal vim it does not have a IDE friendly output, unless you parse the buffers for some responses or change it to fit your needs, most of the functionality is already built.

basicBrogrammer commented 6 years ago

I was going to mention magit but I see you've already heard. I would like to suggest if this "git integration" isn't similar to magit. Could you add the git commands used to the oni api so that I could build an oni magit plugin? 🤔

akinsho commented 6 years ago

@basicBrogrammer we've implemented a Git vcs provider for oni on master though a lot of the functionality is still experimental it includes a sidebar pane for staging, unstaging, commiting, uncommiting files as well as a menu for switching branches, the providers are on the api so you can create plugins etc. with it but the idea is that oni core i.e. the sidebar and menu items should provide most functionality. https://github.com/onivim/oni/wiki/Configuration#version-control

We also merged a buffer layer that adds a git blame per line as an example of some of the functionality that can be created.

You can try it out on master and leave some feedback, or it should be out with the next release

basicBrogrammer commented 6 years ago

@Akin909 noice! I'm super stoked about this project and would love to get involved. Maybe I'll look into some "good first issues". I'll prolly start playing around with it this weekend

akinsho commented 6 years ago

@basicBrogrammer 😍 that'd be great to have some contributions, think atm we still need to label some of our issues as good first issues but also you can have a look at the projects if youre interested in version control stuff there are a few features there we plan on implementing for the vcs if youre looking for ideas 👍