# neovim-gemini

A Neovim plugin for interacting with the Google AI API (formerly Gemini). Get AI-powered assistance directly within your Neovim editor.

## Requirements

* Neovim 0.8 or higher
* A Google AI API key (obtainable from [https://makersuite.google.com/app/apikey](https://makersuite.google.com/app/apikey))
* `curl` installed on your system
* Treesitter installed with the markdown parser (automatically installed during setup)

## Installation

Use your favorite Neovim package manager. Here's how to install with Lazy.nvim:

```lua
{
  "your_username/neovim-gemini",
  config = function()
    require("gemini").setup()
  end,
}
```

## Configuration

### API Key Setup

Set your API key using one of these methods:

1. Environment variable:
```bash
export GEMINI_API_KEY="your-api-key-here"
```

2. Neovim configuration:
```lua
-- In your init.lua
vim.g.gemini_api_key = "your-api-key-here"
```

### Plugin Configuration

The plugin can be configured during setup. Here's an example with all available options and their defaults:

```lua
require("gemini").setup({
    -- Model configuration
    model = "gemini-2.0-flash", -- The Gemini model to use
    api_url = "https://generativelanguage.googleapis.com/v1/models/%s:generateContent", -- API endpoint URL

    -- Window appearance
    window = {
        -- Window width (can be number or function)
        width = function() 
            return math.floor(vim.o.columns / 3)
        end,
        -- Window height (can be number or function)
        height = function()
            return vim.o.lines - 2
        end,
        border = "rounded",     -- Border style: "none", "single", "double", "rounded"
        title = "Gemini Chat Session",
        title_pos = "center",   -- Title position: "left", "center", "right"
    },

    -- Keymaps in chat window
    mappings = {
        close = 'q',           -- Close chat window
        return_focus = '<Esc>', -- Return to previous window
        new_query = 'i',       -- Start new query
    },

    -- Highlight groups for chat messages
    highlights = {
        user = "GeminiUser",         -- Highlight group for user messages
        separator = "GeminiSeparator", -- Highlight group for message separators
    },
})
```

### Configuration Options

#### Model Configuration
- `model`: The Gemini model to use (default: "gemini-2.0-flash")
- `api_url`: The Google AI API endpoint URL format (default: "https://generativelanguage.googleapis.com/v1/models/%s:generateContent")

#### Window Appearance
- `window.width`: Width of the chat window (number or function)
- `window.height`: Height of the chat window (number or function)
- `window.border`: Border style ("none", "single", "double", "rounded")
- `window.title`: Title of the chat window
- `window.title_pos`: Position of the title ("left", "center", "right")

#### Chat Window Keymaps
- `mappings.close`: Key to close the chat window (default: 'q')
- `mappings.return_focus`: Key to return to previous window (default: '<Esc>')
- `mappings.new_query`: Key to start a new query (default: 'i')

#### Highlight Groups
- `highlights.user`: Highlight group for user messages (default: "GeminiUser")
- `highlights.separator`: Highlight group for message separators (default: "GeminiSeparator")

### Customizing Highlights

The plugin defines two highlight groups that you can customize:

```lua
-- In your init.lua or colorscheme
vim.api.nvim_set_hl(0, "GeminiUser", { fg = "#EBCB8B", bold = true })
vim.api.nvim_set_hl(0, "GeminiSeparator", { fg = "#616E88", bold = true })
```

### Default Global Keymaps

The plugin sets up the following default keymaps in normal mode:

- `<leader>gc`: Open chat window for a new query
- `<leader>gs`: Open chat window with current buffer as context
- `<leader>gq`: Clear chat history

You can override these by adding your own mappings after setup:

```lua
-- Example of custom keymaps
vim.keymap.set("n", "<leader>m", function()
    require("gemini").prompt_query()
end, { desc = "Chat with Gemini AI" })

vim.keymap.set("n", "<leader>M", function()
    require("gemini").prompt_query(vim.api.nvim_buf_get_lines(0, 0, -1, false))
end, { desc = "Chat with Gemini AI (with buffer context)" })
```

### Configuration Examples

1. **Custom Window Size (Percentage Based)**:
```lua
require("gemini").setup({
    window = {
        width = function()
            -- Use 40% of screen width
            return math.floor(vim.o.columns * 0.4)
        end,
        height = function()
            -- Use 80% of screen height
            return math.floor(vim.o.lines * 0.8)
        end
    }
})
```

2. **Fixed Window Dimensions**:
```lua
require("gemini").setup({
    window = {
        width = 80,   -- Fixed width of 80 columns
        height = 40,  -- Fixed height of 40 lines
    }
})
```

3. **Custom Appearance**:
```lua
require("gemini").setup({
    window = {
        border = "double",
        title = "AI Assistant",
        title_pos = "left"
    },
    highlights = {
        user = "Statement",     -- Use built-in highlight group
        separator = "Comment"   -- Use built-in highlight group
    }
})
```

4. **Custom Keymaps**:
```lua
require("gemini").setup({
    mappings = {
        close = '<C-c>',
        return_focus = '<C-w>',
        new_query = 'a'
    }
})
```

## Usage

The plugin provides several ways to interact with Gemini:

1. Command Mode:
```vim
:Gemini What is SOLID in software engineering?
```

2. Simple Query:
- Press `<leader>gc` to open an input prompt (mnemonic: 'gemini chat')
- Type your query and press Enter

3. Context-Aware Query:
- Press `<leader>gs` to open an input prompt (mnemonic: 'gemini sync')
- This will send your current buffer's content as context along with your query
- Useful for code-related questions about the file you're working on

4. Clear Chat History:
- Press `<leader>gq` to clear the chat history (mnemonic: 'gemini quit')
- This will clear both the chat window and conversation history
- You can also use the `:GeminiClearChat` command

### Chat Window Controls

The chat window appears on the right side of your editor and provides the following controls:

- `i`: Enter a new query
  - If the chat was started with buffer context (using `<leader>gs`), subsequent queries will maintain that context
  - If started without context (using `<leader>gc`), queries will be context-free
- `q`: Close the chat window (history is preserved)
- `<Esc>`: Return focus to previous buffer
- Normal mode scrolling commands (`j`, `k`, `<C-d>`, `<C-u>`, etc.) work as expected

Chat Window Display:
- Your latest query is automatically positioned at the top of the window
- The AI's response appears directly below your query
- Previous conversation history is accessible by scrolling up
- Messages are clearly marked with "User:" and "Assistant:" prefixes
- Messages are separated by horizontal lines for better readability

Chat Window Restrictions:
- Leader key commands (including telescope/file operations) are disabled
- Command mode (`:`) is disabled
- Only basic navigation and chat-specific commands are allowed
- A warning message appears if you attempt restricted operations

### Chat Commands

- `:GeminiClearChat`: Clear the conversation history and chat window
- `:Gemini <query>`: Send a query directly from command mode

## Features

- Floating window interface with persistent chat history
- Non-blocking API calls
- Error handling and notifications
- Easy-to-use command and keymap interface
- Support for the latest Gemini 2.0 Flash model
- Markdown syntax highlighting for responses
- Context-aware queries using current buffer content
- Smart conversation display with latest query at the top
- Protected chat window to prevent accidental modifications

## Troubleshooting

If you encounter issues:

1. Verify your API key is correctly set:
```lua
:lua print(vim.g.gemini_api_key)
```

2. Check if curl is installed:
```bash
curl --version
```

3. Ensure you have billing set up in your Google Cloud project

## License

This project is licensed under the ISC License. See the [LICENSE](LICENSE) file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.