mirror of
				https://github.com/NotAShelf/nvf.git
				synced 2025-10-31 02:52:37 +00:00 
			
		
		
		
	Merge pull request #249 from NotAShelf/plugins/fugitive
plugins/git: add vim-fugitive; modularize
This commit is contained in:
		
				commit
				
					
						44120bd5b6
					
				
			
		
					 12 changed files with 206 additions and 130 deletions
				
			
		|  | @ -148,7 +148,7 @@ inputs: let | ||||||
|       git = { |       git = { | ||||||
|         enable = true; |         enable = true; | ||||||
|         gitsigns.enable = true; |         gitsigns.enable = true; | ||||||
|         gitsigns.codeActions = false; # throws an annoying debug message |         gitsigns.codeActions.enable = false; # throws an annoying debug message | ||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|       minimap = { |       minimap = { | ||||||
|  |  | ||||||
							
								
								
									
										17
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										17
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							|  | @ -1653,6 +1653,22 @@ | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "plugin-vim-fugitive": { | ||||||
|  |       "flake": false, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1712554826, | ||||||
|  |         "narHash": "sha256-pmY1EQbupKvsqok9O5omkOWi0BEZ8df7HL0F7ubdY9Q=", | ||||||
|  |         "owner": "tpope", | ||||||
|  |         "repo": "vim-fugitive", | ||||||
|  |         "rev": "dac8e5c2d85926df92672bf2afb4fc48656d96c7", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "tpope", | ||||||
|  |         "repo": "vim-fugitive", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "plugin-vim-illuminate": { |     "plugin-vim-illuminate": { | ||||||
|       "flake": false, |       "flake": false, | ||||||
|       "locked": { |       "locked": { | ||||||
|  | @ -1865,6 +1881,7 @@ | ||||||
|         "plugin-tokyonight": "plugin-tokyonight", |         "plugin-tokyonight": "plugin-tokyonight", | ||||||
|         "plugin-trouble": "plugin-trouble", |         "plugin-trouble": "plugin-trouble", | ||||||
|         "plugin-vim-dirtytalk": "plugin-vim-dirtytalk", |         "plugin-vim-dirtytalk": "plugin-vim-dirtytalk", | ||||||
|  |         "plugin-vim-fugitive": "plugin-vim-fugitive", | ||||||
|         "plugin-vim-illuminate": "plugin-vim-illuminate", |         "plugin-vim-illuminate": "plugin-vim-illuminate", | ||||||
|         "plugin-vim-markdown": "plugin-vim-markdown", |         "plugin-vim-markdown": "plugin-vim-markdown", | ||||||
|         "plugin-vim-repeat": "plugin-vim-repeat", |         "plugin-vim-repeat": "plugin-vim-repeat", | ||||||
|  |  | ||||||
|  | @ -407,6 +407,11 @@ | ||||||
|       flake = false; |       flake = false; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     plugin-vim-fugitive = { | ||||||
|  |       url = "github:tpope/vim-fugitive"; | ||||||
|  |       flake = false; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     plugin-fidget-nvim = { |     plugin-fidget-nvim = { | ||||||
|       url = "github:j-hui/fidget.nvim"; |       url = "github:j-hui/fidget.nvim"; | ||||||
|       flake = false; |       flake = false; | ||||||
|  |  | ||||||
|  | @ -1,86 +0,0 @@ | ||||||
| { |  | ||||||
|   config, |  | ||||||
|   lib, |  | ||||||
|   ... |  | ||||||
| }: let |  | ||||||
|   inherit (builtins) toJSON; |  | ||||||
|   inherit (lib.modules) mkIf mkMerge; |  | ||||||
|   inherit (lib.nvim.binds) addDescriptionsToMappings mkSetExprBinding mkSetLuaBinding pushDownDefault; |  | ||||||
|   inherit (lib.nvim.dag) entryAnywhere; |  | ||||||
| 
 |  | ||||||
|   cfg = config.vim.git; |  | ||||||
| 
 |  | ||||||
|   self = import ./git.nix {inherit lib config;}; |  | ||||||
|   gsMappingDefinitions = self.options.vim.git.gitsigns.mappings; |  | ||||||
| 
 |  | ||||||
|   gsMappings = addDescriptionsToMappings cfg.gitsigns.mappings gsMappingDefinitions; |  | ||||||
| in { |  | ||||||
|   config = mkIf cfg.enable (mkMerge [ |  | ||||||
|     (mkIf cfg.gitsigns.enable (mkMerge [ |  | ||||||
|       { |  | ||||||
|         vim.startPlugins = ["gitsigns-nvim"]; |  | ||||||
| 
 |  | ||||||
|         vim.maps.normal = mkMerge [ |  | ||||||
|           (mkSetExprBinding gsMappings.nextHunk '' |  | ||||||
|             function() |  | ||||||
|               if vim.wo.diff then return ${toJSON gsMappings.nextHunk.value} end |  | ||||||
| 
 |  | ||||||
|               vim.schedule(function() package.loaded.gitsigns.next_hunk() end) |  | ||||||
| 
 |  | ||||||
|               return '<Ignore>' |  | ||||||
|             end |  | ||||||
|           '') |  | ||||||
|           (mkSetExprBinding gsMappings.previousHunk '' |  | ||||||
|             function() |  | ||||||
|               if vim.wo.diff then return ${toJSON gsMappings.previousHunk.value} end |  | ||||||
| 
 |  | ||||||
|               vim.schedule(function() package.loaded.gitsigns.prev_hunk() end) |  | ||||||
| 
 |  | ||||||
|               return '<Ignore>' |  | ||||||
|             end |  | ||||||
|           '') |  | ||||||
| 
 |  | ||||||
|           (mkSetLuaBinding gsMappings.stageHunk "package.loaded.gitsigns.stage_hunk") |  | ||||||
|           (mkSetLuaBinding gsMappings.resetHunk "package.loaded.gitsigns.reset_hunk") |  | ||||||
|           (mkSetLuaBinding gsMappings.undoStageHunk "package.loaded.gitsigns.undo_stage_hunk") |  | ||||||
| 
 |  | ||||||
|           (mkSetLuaBinding gsMappings.stageBuffer "package.loaded.gitsigns.stage_buffer") |  | ||||||
|           (mkSetLuaBinding gsMappings.resetBuffer "package.loaded.gitsigns.reset_buffer") |  | ||||||
| 
 |  | ||||||
|           (mkSetLuaBinding gsMappings.previewHunk "package.loaded.gitsigns.preview_hunk") |  | ||||||
| 
 |  | ||||||
|           (mkSetLuaBinding gsMappings.blameLine "function() package.loaded.gitsigns.blame_line{full=true} end") |  | ||||||
|           (mkSetLuaBinding gsMappings.toggleBlame "package.loaded.gitsigns.toggle_current_line_blame") |  | ||||||
| 
 |  | ||||||
|           (mkSetLuaBinding gsMappings.diffThis "package.loaded.gitsigns.diffthis") |  | ||||||
|           (mkSetLuaBinding gsMappings.diffProject "function() package.loaded.gitsigns.diffthis('~') end") |  | ||||||
| 
 |  | ||||||
|           (mkSetLuaBinding gsMappings.toggleDeleted "package.loaded.gitsigns.toggle_deleted") |  | ||||||
|         ]; |  | ||||||
| 
 |  | ||||||
|         vim.maps.visual = mkMerge [ |  | ||||||
|           (mkSetLuaBinding gsMappings.stageHunk "function() package.loaded.gitsigns.stage_hunk {vim.fn.line('.'), vim.fn.line('v')} end") |  | ||||||
|           (mkSetLuaBinding gsMappings.resetHunk "function() package.loaded.gitsigns.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end") |  | ||||||
|         ]; |  | ||||||
| 
 |  | ||||||
|         vim.binds.whichKey.register = pushDownDefault { |  | ||||||
|           "<leader>g" = "+Gitsigns"; |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         vim.luaConfigRC.gitsigns = entryAnywhere '' |  | ||||||
|           require('gitsigns').setup{} |  | ||||||
|         ''; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       (mkIf cfg.gitsigns.codeActions { |  | ||||||
|         vim.lsp.null-ls.enable = true; |  | ||||||
|         vim.lsp.null-ls.sources.gitsigns-ca = '' |  | ||||||
|           table.insert( |  | ||||||
|             ls_sources, |  | ||||||
|             null_ls.builtins.code_actions.gitsigns |  | ||||||
|           ) |  | ||||||
|         ''; |  | ||||||
|       }) |  | ||||||
|     ])) |  | ||||||
|   ]); |  | ||||||
| } |  | ||||||
|  | @ -1,6 +1,18 @@ | ||||||
| { | {lib, ...}: let | ||||||
|  |   inherit (lib.options) mkEnableOption; | ||||||
|  | in { | ||||||
|   imports = [ |   imports = [ | ||||||
|     ./config.nix |     ./gitsigns | ||||||
|     ./git.nix |     ./vim-fugitive | ||||||
|   ]; |   ]; | ||||||
|  | 
 | ||||||
|  |   options.vim.git = { | ||||||
|  |     enable = mkEnableOption '' | ||||||
|  |       git integration suite. | ||||||
|  | 
 | ||||||
|  |       Enabling this option will enable the following plugins: | ||||||
|  |       * gitsigns | ||||||
|  |       * vim-fugitive | ||||||
|  |     ''; | ||||||
|  |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,40 +0,0 @@ | ||||||
| { |  | ||||||
|   config, |  | ||||||
|   lib, |  | ||||||
|   ... |  | ||||||
| }: let |  | ||||||
|   inherit (lib.options) mkEnableOption; |  | ||||||
|   inherit (lib.nvim.binds) mkMappingOption; |  | ||||||
| in { |  | ||||||
|   options.vim.git = { |  | ||||||
|     enable = mkEnableOption "git integration"; |  | ||||||
| 
 |  | ||||||
|     gitsigns = { |  | ||||||
|       enable = mkEnableOption "gitsigns" // {default = config.vim.git.enable;}; |  | ||||||
| 
 |  | ||||||
|       mappings = { |  | ||||||
|         nextHunk = mkMappingOption "Next hunk [Gitsigns]" "]c"; |  | ||||||
|         previousHunk = mkMappingOption "Previous hunk [Gitsigns]" "[c"; |  | ||||||
| 
 |  | ||||||
|         stageHunk = mkMappingOption "Stage hunk [Gitsigns]" "<leader>hs"; |  | ||||||
|         undoStageHunk = mkMappingOption "Undo stage hunk [Gitsigns]" "<leader>hu"; |  | ||||||
|         resetHunk = mkMappingOption "Reset hunk [Gitsigns]" "<leader>hr"; |  | ||||||
| 
 |  | ||||||
|         stageBuffer = mkMappingOption "Stage buffer [Gitsigns]" "<leader>hS"; |  | ||||||
|         resetBuffer = mkMappingOption "Reset buffer [Gitsigns]" "<leader>hR"; |  | ||||||
| 
 |  | ||||||
|         previewHunk = mkMappingOption "Preview hunk [Gitsigns]" "<leader>hP"; |  | ||||||
| 
 |  | ||||||
|         blameLine = mkMappingOption "Blame line [Gitsigns]" "<leader>hb"; |  | ||||||
|         toggleBlame = mkMappingOption "Toggle blame [Gitsigns]" "<leader>tb"; |  | ||||||
| 
 |  | ||||||
|         diffThis = mkMappingOption "Diff this [Gitsigns]" "<leader>hd"; |  | ||||||
|         diffProject = mkMappingOption "Diff project [Gitsigns]" "<leader>hD"; |  | ||||||
| 
 |  | ||||||
|         toggleDeleted = mkMappingOption "Toggle deleted [Gitsigns]" "<leader>td"; |  | ||||||
|       }; |  | ||||||
| 
 |  | ||||||
|       codeActions = mkEnableOption "gitsigns codeactions through null-ls"; |  | ||||||
|     }; |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
							
								
								
									
										88
									
								
								modules/plugins/git/gitsigns/config.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								modules/plugins/git/gitsigns/config.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,88 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   inherit (builtins) toJSON; | ||||||
|  |   inherit (lib.modules) mkIf mkMerge; | ||||||
|  |   inherit (lib.nvim.binds) addDescriptionsToMappings mkSetExprBinding mkSetLuaBinding pushDownDefault; | ||||||
|  |   inherit (lib.nvim.dag) entryAnywhere; | ||||||
|  | 
 | ||||||
|  |   cfg = config.vim.git.gitsigns; | ||||||
|  | 
 | ||||||
|  |   self = import ./gitsigns.nix {inherit lib config;}; | ||||||
|  |   gsMappingDefinitions = self.options.vim.git.gitsigns.mappings; | ||||||
|  | 
 | ||||||
|  |   gsMappings = addDescriptionsToMappings cfg.mappings gsMappingDefinitions; | ||||||
|  | in { | ||||||
|  |   config = mkIf cfg.enable (mkMerge [ | ||||||
|  |     { | ||||||
|  |       vim = { | ||||||
|  |         startPlugins = ["gitsigns-nvim"]; | ||||||
|  | 
 | ||||||
|  |         maps = { | ||||||
|  |           normal = mkMerge [ | ||||||
|  |             (mkSetExprBinding gsMappings.nextHunk '' | ||||||
|  |               function() | ||||||
|  |                 if vim.wo.diff then return ${toJSON gsMappings.nextHunk.value} end | ||||||
|  | 
 | ||||||
|  |                 vim.schedule(function() package.loaded.gitsigns.next_hunk() end) | ||||||
|  | 
 | ||||||
|  |                 return '<Ignore>' | ||||||
|  |               end | ||||||
|  |             '') | ||||||
|  |             (mkSetExprBinding gsMappings.previousHunk '' | ||||||
|  |               function() | ||||||
|  |                 if vim.wo.diff then return ${toJSON gsMappings.previousHunk.value} end | ||||||
|  | 
 | ||||||
|  |                 vim.schedule(function() package.loaded.gitsigns.prev_hunk() end) | ||||||
|  | 
 | ||||||
|  |                 return '<Ignore>' | ||||||
|  |               end | ||||||
|  |             '') | ||||||
|  | 
 | ||||||
|  |             (mkSetLuaBinding gsMappings.stageHunk "package.loaded.gitsigns.stage_hunk") | ||||||
|  |             (mkSetLuaBinding gsMappings.resetHunk "package.loaded.gitsigns.reset_hunk") | ||||||
|  |             (mkSetLuaBinding gsMappings.undoStageHunk "package.loaded.gitsigns.undo_stage_hunk") | ||||||
|  | 
 | ||||||
|  |             (mkSetLuaBinding gsMappings.stageBuffer "package.loaded.gitsigns.stage_buffer") | ||||||
|  |             (mkSetLuaBinding gsMappings.resetBuffer "package.loaded.gitsigns.reset_buffer") | ||||||
|  | 
 | ||||||
|  |             (mkSetLuaBinding gsMappings.previewHunk "package.loaded.gitsigns.preview_hunk") | ||||||
|  | 
 | ||||||
|  |             (mkSetLuaBinding gsMappings.blameLine "function() package.loaded.gitsigns.blame_line{full=true} end") | ||||||
|  |             (mkSetLuaBinding gsMappings.toggleBlame "package.loaded.gitsigns.toggle_current_line_blame") | ||||||
|  | 
 | ||||||
|  |             (mkSetLuaBinding gsMappings.diffThis "package.loaded.gitsigns.diffthis") | ||||||
|  |             (mkSetLuaBinding gsMappings.diffProject "function() package.loaded.gitsigns.diffthis('~') end") | ||||||
|  | 
 | ||||||
|  |             (mkSetLuaBinding gsMappings.toggleDeleted "package.loaded.gitsigns.toggle_deleted") | ||||||
|  |           ]; | ||||||
|  | 
 | ||||||
|  |           visual = mkMerge [ | ||||||
|  |             (mkSetLuaBinding gsMappings.stageHunk "function() package.loaded.gitsigns.stage_hunk {vim.fn.line('.'), vim.fn.line('v')} end") | ||||||
|  |             (mkSetLuaBinding gsMappings.resetHunk "function() package.loaded.gitsigns.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end") | ||||||
|  |           ]; | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         binds.whichKey.register = pushDownDefault { | ||||||
|  |           "<leader>g" = "+Gitsigns"; | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         luaConfigRC.gitsigns = entryAnywhere '' | ||||||
|  |           require('gitsigns').setup{} | ||||||
|  |         ''; | ||||||
|  |       }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     (mkIf cfg.codeActions.enable { | ||||||
|  |       vim.lsp.null-ls.enable = true; | ||||||
|  |       vim.lsp.null-ls.sources.gitsigns-ca = '' | ||||||
|  |         table.insert( | ||||||
|  |           ls_sources, | ||||||
|  |           null_ls.builtins.code_actions.gitsigns | ||||||
|  |         ) | ||||||
|  |       ''; | ||||||
|  |     }) | ||||||
|  |   ]); | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								modules/plugins/git/gitsigns/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								modules/plugins/git/gitsigns/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | { | ||||||
|  |   imports = [ | ||||||
|  |     ./config.nix | ||||||
|  |     ./gitsigns.nix | ||||||
|  |   ]; | ||||||
|  | } | ||||||
							
								
								
									
										41
									
								
								modules/plugins/git/gitsigns/gitsigns.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								modules/plugins/git/gitsigns/gitsigns.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   inherit (lib.options) mkEnableOption; | ||||||
|  |   inherit (lib.modules) mkRenamedOptionModule; | ||||||
|  |   inherit (lib.nvim.binds) mkMappingOption; | ||||||
|  | in { | ||||||
|  |   imports = [ | ||||||
|  |     (mkRenamedOptionModule ["vim" "git" "gitsigns" "codeActions" "vim" "gitsigns"] ["vim" "git" "gitsigns" "codeActions" "enable"]) | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   options.vim.git.gitsigns = { | ||||||
|  |     enable = mkEnableOption "gitsigns" // {default = config.vim.git.enable;}; | ||||||
|  | 
 | ||||||
|  |     codeActions.enable = mkEnableOption "gitsigns codeactions through null-ls"; | ||||||
|  | 
 | ||||||
|  |     mappings = { | ||||||
|  |       nextHunk = mkMappingOption "Next hunk [Gitsigns]" "]c"; | ||||||
|  |       previousHunk = mkMappingOption "Previous hunk [Gitsigns]" "[c"; | ||||||
|  | 
 | ||||||
|  |       stageHunk = mkMappingOption "Stage hunk [Gitsigns]" "<leader>hs"; | ||||||
|  |       undoStageHunk = mkMappingOption "Undo stage hunk [Gitsigns]" "<leader>hu"; | ||||||
|  |       resetHunk = mkMappingOption "Reset hunk [Gitsigns]" "<leader>hr"; | ||||||
|  | 
 | ||||||
|  |       stageBuffer = mkMappingOption "Stage buffer [Gitsigns]" "<leader>hS"; | ||||||
|  |       resetBuffer = mkMappingOption "Reset buffer [Gitsigns]" "<leader>hR"; | ||||||
|  | 
 | ||||||
|  |       previewHunk = mkMappingOption "Preview hunk [Gitsigns]" "<leader>hP"; | ||||||
|  | 
 | ||||||
|  |       blameLine = mkMappingOption "Blame line [Gitsigns]" "<leader>hb"; | ||||||
|  |       toggleBlame = mkMappingOption "Toggle blame [Gitsigns]" "<leader>tb"; | ||||||
|  | 
 | ||||||
|  |       diffThis = mkMappingOption "Diff this [Gitsigns]" "<leader>hd"; | ||||||
|  |       diffProject = mkMappingOption "Diff project [Gitsigns]" "<leader>hD"; | ||||||
|  | 
 | ||||||
|  |       toggleDeleted = mkMappingOption "Toggle deleted [Gitsigns]" "<leader>td"; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								modules/plugins/git/vim-fugitive/config.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								modules/plugins/git/vim-fugitive/config.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   inherit (lib.modules) mkIf; | ||||||
|  | 
 | ||||||
|  |   cfg = config.vim.git.vim-fugitive; | ||||||
|  | in { | ||||||
|  |   config = mkIf cfg.enable { | ||||||
|  |     vim.startPlugins = ["vim-fugitive"]; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								modules/plugins/git/vim-fugitive/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								modules/plugins/git/vim-fugitive/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | { | ||||||
|  |   imports = [ | ||||||
|  |     ./config.nix | ||||||
|  |     ./vim-fugitive.nix | ||||||
|  |   ]; | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								modules/plugins/git/vim-fugitive/vim-fugitive.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								modules/plugins/git/vim-fugitive/vim-fugitive.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | ||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   lib, | ||||||
|  |   ... | ||||||
|  | }: let | ||||||
|  |   inherit (lib.options) mkEnableOption; | ||||||
|  | in { | ||||||
|  |   options.vim.git.vim-fugitive = { | ||||||
|  |     enable = mkEnableOption "vim-fugitive" // {default = config.vim.git.enable;}; | ||||||
|  | 
 | ||||||
|  |     # TODO: sane default keybinds for vim-fugitive | ||||||
|  |     # mappings = {}; | ||||||
|  |   }; | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 GitHub
					GitHub