Skip to content

Conversation

marcosktsz
Copy link

@marcosktsz marcosktsz commented Jun 15, 2025

Pull Request

Description

This pull request introduces floating window support to claude-code.nvim, enabling users to open the Claude Code terminal in a floating Neovim window. The implementation adds a new ‎position = "floating" option to the window configuration, along with customizable floating window settings such as width, height, and border style.

Type of Change

Please check the options that are relevant:

  • Bug fix (non-breaking change that fixes an issue)
  • [ x] New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Code refactoring
  • Performance improvement
  • Other (please describe):

Checklist

Please check all that apply:

  • [ x] I have read the CONTRIBUTING document
  • [x ] My code follows the style guidelines of this project
  • [x ] I have commented my code, particularly in hard-to-understand areas
  • [x ] I have made corresponding changes to the documentation
  • [x ] My changes generate no new warnings
  • [ x] I have tested with the actual Claude Code CLI tool
  • I have tested in different environments (if applicable)

Screenshots (if applicable)

Screenshot 2025-06-15 at 16 12 49 ![Screenshot 2025-06-15 at 16 12 49 (2)](https://github.com/user-attachments/assets/cbcf0562-09a1-4b19-84c0-a0f2db114280)

Summary by CodeRabbit

  • New Features
    • Introduced support for displaying the terminal in a floating window with configurable size and border options.
    • Added multi-instance floating window management, allowing separate floating terminals per project or directory.
  • Documentation
    • Updated the README to document the new floating window options and configuration parameters.
  • Bug Fixes
    • Improved backward compatibility by migrating legacy floating window configurations automatically.

MartianGreed and others added 6 commits June 15, 2025 16:07
When Claude Code runs inside Neovim, the NVIM environment variable
points to a socket path instead of the nvim executable. This caused
the test script to fail with permission errors.

The fix checks if NVIM is an executable file (not a socket) before
using it, otherwise falls back to finding nvim in PATH.

This allows tests to run properly both from within Claude Code/Neovim
and from regular terminals.

Added:
- Test script to verify NVIM detection logic works correctly
- Documentation in DEVELOPMENT.md explaining the behavior
- Replace 'which' with POSIX-compliant 'command -v' in test scripts
- Fix markdown formatting issues in DEVELOPMENT.md (add blank lines)
- Separate variable declaration and assignment in test_nvim_detection.sh
- Add robust absolute path resolution using readlink and BASH_SOURCE
- Enhance error handling with 'set -euo pipefail' for strict mode
- Replace unreliable $0 references in bash -c contexts

These changes improve portability, reliability, and follow shell scripting
best practices while addressing all linting and formatting issues.
Copy link

coderabbitai bot commented Jun 15, 2025

Walkthrough

Floating window support was introduced for the plugin's terminal interface. Configuration and documentation were updated to include floating window options, and a new module was added to manage floating window lifecycle and state. The terminal module now delegates to this floating window logic when the floating position is specified. Public APIs were extended accordingly.

Changes

File(s) Change Summary
README.md Updated tagline formatting; documented floating window config options and usage.
lua/claude-code/config.lua Added floating window config schema, validation, migration, and defaults.
lua/claude-code/floating.lua New module for floating window lifecycle management and multi-instance support.
lua/claude-code/init.lua Exposed floating window management as a new public field in the main module.
lua/claude-code/keymaps.lua Added a blank line for formatting; no functional changes.
lua/claude-code/terminal.lua Delegates to floating window logic if position is set to 'floating'; preserves existing logic otherwise.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Plugin
    participant Terminal
    participant Floating

    User->>Plugin: Trigger terminal toggle
    Plugin->>Plugin: Check config.window.position
    alt position == "floating"
        Plugin->>Floating: toggle(claude_code, config, git)
        alt Floating window is open
            Floating->>Floating: Close floating window
        else Floating window is closed
            Floating->>Floating: Create floating window & terminal
        end
    else position != "floating"
        Plugin->>Terminal: toggle(claude_code, config, git)
        Terminal->>Terminal: Open/close terminal in split window
    end
Loading

Poem

In a window that floats, I now can appear,
Above your code, I hover near.
With borders and size, set just right,
I pop up gently, light as a kite.
Rabbits rejoice—such nimble delight!
Now terminals float, and all feels light.
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (7)
lua/claude-code/config.lua (4)

17-24: Clarify & constrain border type

border is validated as string|table, but the docs don’t say what a “table” should look like (4-element style array? a map?). Consider tightening the spec or documenting the accepted table shape to avoid user confusion.


80-90: Default position comment still implies split-only values

The comment string "botright", "topleft", "vertical", "floating", etc. omits the existing "vsplit"/"rightbelow vsplit" values used elsewhere in the code. Aligning the doc with the actual parser would prevent mismatch between docs and behaviour.


174-204: Validation should be conditional on position == "floating"

Right now any config that happens to define window.floating is validated, even if the user chose a split position.
That means perfectly valid split configs that keep helper data under window.floating could fail.
Wrap the validation block in:

if config.window.position == 'floating' then
  -- existing validation …
end

to avoid false-positives.


340-359: Avoid mutating the caller’s user_config table

parse_config edits user_config in place (lines 341-351). Side-effects here can surprise callers who reuse the same table.
Safer pattern:

-  if user_config and user_config.floating then
+  local cfg = vim.deepcopy(user_config or {})
+  if cfg.floating then-    user_config = cfg
+    user_config = cfg
   end
lua/claude-code/init.lua (1)

25-45: Exporting floating table is fine, but document public API

External plugins can now rely on require('claude-code').floating. Please add a short note in the module header or README “Public API” section so future refactors don’t break consumers inadvertently.

lua/claude-code/floating.lua (2)

21-29: Factor out common helper to avoid duplication

get_instance_identifier is byte-for-byte identical to the version in terminal.lua. Consider moving it to a shared util module and re-using it from both places to keep behaviour in sync and reduce maintenance overhead.


34-41: Guard against headless UI / oversize ratios

vim.api.nvim_list_uis()[1] is nil in headless sessions, which will raise an error here.
Additionally, if floating_config.width or height is set to a value ≥ 1, the calculated dimensions can exceed the screen and produce a negative row/col. Please add:

local ui = vim.api.nvim_list_uis()[1] or { width = 80, height = 24 }
width  = math.min(ui.width,  math.floor(ui.width  * floating_config.width))
height = math.min(ui.height, math.floor(ui.height * floating_config.height))

or clamp via math.max/min.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 275c476 and b870b3c.

📒 Files selected for processing (6)
  • README.md (2 hunks)
  • lua/claude-code/config.lua (4 hunks)
  • lua/claude-code/floating.lua (1 hunks)
  • lua/claude-code/init.lua (3 hunks)
  • lua/claude-code/keymaps.lua (1 hunks)
  • lua/claude-code/terminal.lua (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
lua/claude-code/floating.lua (1)
lua/claude-code/terminal.lua (1)
  • get_instance_identifier (23-31)
🔇 Additional comments (3)
lua/claude-code/keymaps.lua (1)

25-26: No functional impact – blank line only

Nothing to comment on here.

README.md (1)

96-106: Good doc update

Docs accurately reflect the new floating options.

lua/claude-code/terminal.lua (1)

103-107: State divergence when delegating to floating windows

terminal.toggle exits early for floating, but it never sets
claude_code.claude_code.current_instance nor stores the buffer in
claude_code.claude_code.instances.
Down-stream logic (e.g. keymaps.setup_terminal_navigation, force_insert_mode) expects those fields to be populated and will silently fail for floating windows.

Request: ensure floating.toggle populates / updates the same state table or update consumers to look at claude_code.floating.

Comment on lines +189 to +197
vim.api.nvim_create_autocmd({ 'WinClosed' }, {
buffer = bufnr,
callback = function()
if M.floating.instances[instance_id] then
M.floating.instances[instance_id].winid = nil
end
end,
once = true,
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

once = true prevents cleanup on subsequent windows

The WinClosed autocommand fires only for the first window created from this buffer; when the user re-opens and later manually closes the floating window again, winid is left stale, causing is_open() to mis-report until the next toggle. Drop once = true or recreate the autocommand each time you open a new window.

🤖 Prompt for AI Agents
In lua/claude-code/floating.lua around lines 189 to 197, the WinClosed
autocommand uses once = true, which causes it to run only once and not clean up
the winid on subsequent window closures. To fix this, remove the once = true
option so the autocommand triggers every time the floating window is closed,
ensuring the winid is properly cleared each time.

Comment on lines +148 to +168
local cmd = config.command
if config.git and config.git.use_git_root then
local git_root = git.get_git_root()
if git_root then
-- Use pushd/popd to change directory
local separator = config.shell.separator
local pushd_cmd = config.shell.pushd_cmd
local popd_cmd = config.shell.popd_cmd
cmd = pushd_cmd
.. ' '
.. git_root
.. ' '
.. separator
.. ' '
.. config.command
.. ' '
.. separator
.. ' '
.. popd_cmd
end
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Shell-command construction is vulnerable to spaces / quoting

Building cmd with string concatenation will break when git_root or config.command contain spaces or shell-metacharacters and can even be exploited if filenames are crafted maliciously. Please quote/escape the segments or, better, use vim.fn.termopen({cmd, arg1, …}, opts) with the list-form to avoid a shell entirely.

🤖 Prompt for AI Agents
In lua/claude-code/floating.lua around lines 148 to 168, the construction of the
shell command string using concatenation is unsafe because it does not handle
spaces or special shell characters in git_root or config.command. To fix this,
avoid building a single shell command string; instead, use vim.fn.termopen with
a list of command and arguments to bypass the shell and handle escaping
automatically. Refactor the code to pass the command and its arguments as a list
rather than a concatenated string.

@greggh
Copy link
Owner

greggh commented Jul 2, 2025

We've just merged in another large floating window PR, and it brought up some merge issues here. This might also be duplication at this point. Can you take a look at the now merged PR and see if this shoiuld be reworked or closed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants