Skip to content

feat: make insert_commented (\o) pipe-chain aware#502

Closed
guilhermegarcia wants to merge 4 commits intoR-nvim:mainfrom
guilhermegarcia:feat/insert-commented-pipe-chain
Closed

feat: make insert_commented (\o) pipe-chain aware#502
guilhermegarcia wants to merge 4 commits intoR-nvim:mainfrom
guilhermegarcia:feat/insert-commented-pipe-chain

Conversation

@guilhermegarcia
Copy link
Contributor

@guilhermegarcia guilhermegarcia commented Feb 9, 2026

Summary

  • insert_commented (\o) now detects multi-line pipe chains and sends the full expression instead of just the current line
  • Supports |>, %>%, %<>%, and %T>% operators
  • Tracks parenthesis depth to handle multi-line function arguments (e.g., mutate(\n...\n))
  • Output is inserted as a comment below the last line of the chain
  • Single-line behavior is unchanged

Motivation

Currently, pressing \o on any line of a multi-line pipe chain like:

c(3, 1, 4, 1, 5) |>
  sort() |>
  rev()

only sends that single line (e.g., print(c(3, 1, 4, 1, 5) |>)), which is an incomplete expression — R produces no output. Pipe chains are arguably the most common multi-line pattern in modern R, so this is a significant usability gap.

Similarly, pipes into multi-line function calls like:

tokens <- tokens |>
    mutate(
      n_pred = 1 / (rang + beta)^alpha,
      residuals = n - n_pred
    )

are now correctly captured as a complete expression by tracking (/) depth.

Approach

Uses a text-based line-walking heuristic with parenthesis depth tracking:

  • Walk up: from the cursor, walk upward while the previous line ends with a pipe operator or while there are unmatched ) needing a ( above
  • Walk down: from the chain start, walk forward while inside unclosed parentheses (depth > 0) or while the line ends with a pipe operator

The collected lines are joined with spaces (not newlines) to avoid issues in the Lua → LSP → rnvimserver → R transport layer.

This avoids the complexity of treesitter (and the synthetic buffer mapping needed for Quarto/Rmd) while covering all practical cases.

Test plan

  • Single line, no pipes: cursor on x <- 5, press \o# [1] 5 below (unchanged behavior)
  • Multi-line native pipe: cursor anywhere in data |> filter() |> summarize() chain → full chain evaluated, output below last line
  • Pipe with multi-line function args: tokens |> mutate(\n...\n) → complete expression captured
  • Pipe with assignment: result <- data |> filter() → assigns and prints
  • Trailing comments stripped: rev() # comment → comment removed before sending
  • Multi-line magrittr pipe: same with %>%
  • Works in Quarto/Rmd R chunks

When the cursor is inside a multi-line pipe chain (|>, %>%, %<>%,
%T>%, or + for ggplot), \ro now collects the full chain instead of
just the current line. The output is inserted as a comment below the
last line of the chain. Single-line behavior is unchanged.
- Walk-down now tracks parenthesis depth so multi-line function args
  (e.g., mutate(\n...\n)) are included in the chain
- Walk-up tracks reverse paren depth so cursor on `)` lines finds
  the matching `(` above
- Remove `+` from pipe operators (printing ggplot objects as comments
  is not useful)
@jalvesaq
Copy link
Member

jalvesaq commented Feb 9, 2026

Thank you! @PMassicotte has made sending code to R pipe-chain aware, and he may want to review this pull request. I can also look at this (but only tomorrow).

@PMassicotte
Copy link
Collaborator

PMassicotte commented Feb 9, 2026

Thank you @guilhermegarcia for this PR.

Can you try the feat/insert-commented-reuse-chain branch (986a6df)? I redid it but leveraging the use of the existing infra based on Treesitter. It should work also in quarto and rmd document.

Peek 2026-02-09 07-48

@PMassicotte
Copy link
Collaborator

@guilhermegarcia
Copy link
Contributor Author

Thanks @PMassicotte! I tested your branch and it works great — much cleaner than my text-based approach. Using the existing treesitter infrastructure makes more sense, and the Quarto/Rmd support is a nice bonus.

Happy to close this PR in favor of your implementation.

@PMassicotte
Copy link
Collaborator

Thanks @PMassicotte! I tested your branch and it works great — much cleaner than my text-based approach. Using the existing treesitter infrastructure makes more sense, and the Quarto/Rmd support is a nice bonus.

Happy to close this PR in favor of your implementation.

Thank you very much for your issue and proposing a solution :)

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.

3 participants