Commit graph

1391 commits

Author SHA1 Message Date
Folke Lemaitre
0b0a58ae4a
fix(picker.actions): <c-g> in list view now prints file path instead of cwd. Fallback to cwd 2025-10-21 08:18:34 +02:00
Folke Lemaitre
b7f811613a
fix(picker.format): added min_width for truncated paths 2025-10-21 08:14:34 +02:00
Folke Lemaitre
d5b6d30b5e
fix(picker.format): simplified resolvable formatters and more correct 2025-10-21 08:06:43 +02:00
Tod Morrison
1c3f15cb54
fix(image): correct render fallback to handle "editor" relative position (#2297)
PR #2296 had the conditionals in the wrong order and with an "or"
instead of an "and". This should finally fix the issue and pass
stylelua.

## Description

The correct condition for correcting the off-by-one is:
```
    if
      (Snacks.config.styles.snacks_image.relative ~= "editor")
      and ((vim.o.showtabline == 2) or (vim.o.showtabline == 1 and vim.fn.tabpagenr("$") > 1))
    then
```
This patch gets the conditional in the right order
2025-10-21 07:36:13 +02:00
Folke Lemaitre
faa6abacb4
feat(picker): mapped <c-g> to print_cwd in list. See #2244 2025-10-21 07:25:35 +02:00
Folke Lemaitre
14dd362d5d
fix(git): always check parents for git root to fix an issue with git submodules. Closes #2143 2025-10-21 07:21:03 +02:00
Tod Morrison
c552cea131
fix(image): correct render fallback to handle "editor" relative position (#2296)
In PR 1560, @phanen reported an additional case that was not handled by
that fix when the style is set to `relative = "editor"`. This new patch
adds a check to handle that case.

## Description ##

This patch adds a check for `Snacks.config.styles.snacks_image.relative
~= "editor"` to the conditional in render_fallback that handles the
off-by-one error. The previous patch fixed the relative = "cursor" case,
but introduced a regression in the relative = "editor" case.
2025-10-21 07:01:50 +02:00
Folke Lemaitre
1b4205eb1a
fix(picker): fixup for pickers that dont display files
Some checks are pending
CI / ci (push) Waiting to run
2025-10-20 23:17:18 +02:00
Folke Lemaitre
a5d29646e5
fix(picker.format): correcter max_width for truncpath 2025-10-20 23:15:31 +02:00
Folke Lemaitre
9ad5d5374a
feat(picker): flexible filename format (#2294)
## Description

This PR builds on top of #743 to add flexible filename formatting in the
picker.

### Changes:
- **Flexible path truncation**: Added support for different truncation
strategies (`left`, `center`, `right`) instead of just a fixed number
- `left`: truncates the beginning of the path (e.g.,
`…/path/to/file.lua`)
- `center`: truncates the middle of the path (default behavior, e.g.,
`~/pro…/file.lua`)
  - `right`: truncates the end of the path (e.g., `~/projects/long…`)
- **Dynamic width calculation**: The filename formatter now adapts to
available window width using a resolve function
- **Enhanced truncate utility**: Updated `M.truncate()` to support
left-side truncation

### Implementation:
The filename formatter now uses a `resolve` function that receives
context including the picker, item, current offset, and maximum
available width. This allows the formatter to make intelligent decisions
about how to display the path based on actual available space.

## Related Issue(s)
- Based on #743
- Addresses dynamic path formatting needs

## Technical Details
The implementation introduces:
1. `snacks.picker.format.ctx` - context passed to resolve functions
2. `snacks.picker.format.resolve` - callback type for dynamic formatting
3. `Snacks.picker.highlight.resolve()` - resolves flex text elements in
highlight arrays

---------

Co-authored-by: qw457812 <37494864+qw457812@users.noreply.github.com>
2025-10-20 23:02:52 +02:00
Mohamed Boussaffa
6af1e76758
fix(picker.qflist): error with qflist picker when the list contains invalid items (#2293)
## Description

There is an issue with the quick fix list picker
This happens when list contains some incomplete or invalid items.
The fallback mechanism in the picker have 2 typos that trigger an error
trap

* The item line number field is item.lnum and not item.line
* A check is done on item.text twice in the same if condition, it should
to item.text and item.lnum

## Related Issue(s)

<!--
  If this PR fixes any issues, please link to the issue here.
  - Fixes #<issue_number>
-->

## Screenshots

<!-- Add screenshots of the changes if applicable. -->
2025-10-20 20:09:08 +02:00
Folke Lemaitre
9b80137ace
feat(input): added support for a custom highlight functions. Closes #2216 2025-10-20 20:08:22 +02:00
Folke Lemaitre
595963140e
fix(picker.recent): include closed / unlisted buffers in recent. Closes #1745 2025-10-20 18:42:26 +02:00
Folke Lemaitre
30687d195b
feat(image): added clear fun. Closes #1394 2025-10-20 18:27:14 +02:00
Folke Lemaitre
774bf9d8c8
fix(util): only use mini.icons if it has been setup. Closes #2199 2025-10-20 17:53:11 +02:00
Glenn Waters
a32735b9e8
fix(picker.core): respect camelCase for scoring when ignorecase is true (#1601)
## Description

<!-- Describe the big picture of your changes to communicate to the
maintainers
  why we should accept this pull request. -->
Because the search item was lowercased before it was scored, camelCase
would not be triggered to give the intended bonus.

This was the simplest and fastest (code execution wise) fix I could see.

## Related Issue(s)
Fixes: https://github.com/folke/snacks.nvim/issues/1599

## Screenshots

<!-- Add screenshots of the changes if applicable. -->
2025-10-20 08:50:18 -07:00
Folke Lemaitre
f39d1144e7
fix(picker.man): make tab/split/vsplit work. Closes #2171 2025-10-20 17:46:10 +02:00
Folke Lemaitre
abee3c9eff
fix(picker.git): use unmerged icon for unmerged. Fixes #1531 2025-10-20 17:31:43 +02:00
Aaron Weisberg
a012f394c9
fix(picker.git_diff): use absolute path when adding buffer to avoid duplicates (#1819)
## Description

Uses absolute path for setting the cursor
<!-- Describe the big picture of your changes to communicate to the
maintainers
  why we should accept this pull request. -->

## Related Issue(s)

Fixes #1818 
<!--
  If this PR fixes any issues, please link to the issue here.
  - Fixes #<issue_number>
-->

## Screenshots

<!-- Add screenshots of the changes if applicable. -->

---------

Co-authored-by: Aaron Weisberg <aaron.weisberg@quizlet.com>
2025-10-20 16:03:03 +02:00
Folke Lemaitre
259cb01d7d
style: format 2025-10-20 15:58:58 +02:00
Daniel Danner
93f43ca10f
fix(git): set diff.noprefix=false for git diff to ensure correct format (#2174)
## Description

Parsing the output of git diff here depends on its exact format. The
user environment might be set up with diff.noprefix, in which case the
parsing fails, because the `a/` and `b/` prefixes for the paths is
missing. Passing `-c diff.noprefix=false` to the call overrides this.
<!-- Describe the big picture of your changes to communicate to the
maintainers
  why we should accept this pull request. -->

## Related Issue(s)

<!--
  If this PR fixes any issues, please link to the issue here.
  - Fixes #<issue_number>
-->

## Screenshots

<!-- Add screenshots of the changes if applicable. -->
2025-10-20 15:54:26 +02:00
Zhou Fang
bd6ee23546
feat(picker): add toggle_regex for grep (#1594)
## For people who want to use it NOW!

Use `init` to hack the latest version before this PR merge.
```lua
{
  "folke/snacks.nvim",
  init = function()
    local sources = require("snacks.picker.config.sources")
    sources.grep.toggles = {
      regex = { value = true },
    }
    sources.grep.win = {
      input = {
        keys = {
          ["<a-r>"] = { "toggle_regex", mode = { "n", "i" }, desc = "Toggle Regex" },
        },
      },
    }
  end,
},
```


## Description

This PR adds a new keymap `<a-r>` for toggling the regex in grep picker.

It allows user to get faster when searching some special strings like
`$props()`, or just put a part of line `test to jump faster.

## Related Issue(s)

<!--
  If this PR fixes any issues, please link to the issue here.
  - Fixes #<issue_number>
-->

## Screenshots


https://github.com/user-attachments/assets/2442b21c-898f-4682-a966-5a82abdd23e8

---------

Co-authored-by: Folke Lemaitre <folke.lemaitre@gmail.com>
2025-10-20 15:52:54 +02:00
Jakub F. Bortlík
d0a5310417
fix(picker): do not record consecutive duplicate history (#2040)
## Description

Before this fix, identical items are added to history repeatedly. This
PR fixes this by only adding an item to history if it's different from
the last recorded value.

This doesn't completely remove duplicate entries in the history, it only
prevents consecutive identical entries.
2025-10-20 15:40:09 +02:00
Folke Lemaitre
19ff343a16
style: format 2025-10-20 15:29:47 +02:00
Tharun T
a4664298ba
fix(gitbrowse): send commit as a opt when calling gitbrowse (#2289)
## Description

- I was trying to go to the commit page from fugitive commit buffers
- but snacks.nvim doesn't support this (fugitive does) and so I wanted a
way to send the commit IDs to the gitbrowse function after parsing it
myself in my dotfiles

### changes
- added `commit` option to `gitbrowse` config to allow passing commit
hashes directly instead of only auto-detecting from cursor word or file
history
- only falls back to auto-detection when `commit` is not explicitly
provided

## Related Issue(s)

<!--
  If this PR fixes any issues, please link to the issue here.
  - Fixes #<issue_number>
-->

## Screenshots

<!-- Add screenshots of the changes if applicable. -->
2025-10-20 15:28:30 +02:00
Tristan Kapous
3ccab9736b
feat(toggle): allow notification customization via function (#2247)
This is a very small change that make it possible to configure the
notification for toggles.

For example, we can display icons instead of the default 'Enabled' /
'Disabled' text, or not use bold.

<img width="454" height="242" alt="image"
src="https://github.com/user-attachments/assets/56f2f4c9-ef04-42df-b498-205416103a7a"
/>

<img width="454" height="242" alt="image"
src="https://github.com/user-attachments/assets/a0b1fb6f-4d34-47aa-b790-a18fc790e1c3"
/>
2025-10-20 15:26:26 +02:00
Bao
ac6154688b
fix(notifier): keep filtered notifications in history (#2209)
## Description

the documentation for `snacks.notifier.Config` says:


f6c06415a2/lua/snacks/notifier.lua (L120-L122)

But currently all notifications filtered out by either `opts.level` or
`opts.filter` are also omitted from the history, on top of being
suppressed from displaying

Fixes this regression

## Related Issue(s)

* Related to #93, although that was caused by misconfiguration. This one
is an actual bug
* Closes #2208 

## Screenshots

n/a
2025-10-20 15:23:10 +02:00
starbased
2aacf55082
fix(terminal): set buffer when opening terminal with position='current' (#2162)
## Description

When opening a terminal with position='current', the terminal buffer
wasn't being set in the current window, causing the original buffer
content to remain visible with terminal styling applied.

This fix adds a call to vim.api.nvim_win_set_buf() to properly set the
terminal buffer when using position='current'. Also updates type
annotations to include the 'current' position option and adds tests to
prevent regression.

Credit to the solution to by @Baricus in issue #2148.

## Related Issue(s)

Fixes #2148

Co-authored-by: Baricus <31926270+Baricus@users.noreply.github.com>
2025-10-20 15:22:02 +02:00
Alexander Frolov
9ebf052fef
fix(gitbrowse): fixed urls for gitlab (#2073)
## Description

GitLab highlighting uses a different scheme for range of lines

fb2f3ce787/app/assets/javascripts/repository/mixins/highlight_mixin.js (L114)

## Related Issue(s)

<!--
  If this PR fixes any issues, please link to the issue here.
  - Fixes #<issue_number>
-->

## Screenshots

<!-- Add screenshots of the changes if applicable. -->
2025-10-20 15:15:21 +02:00
Aaron Weisberg
fb54927ab0
fix(zen): make zoom and minimizing work in terminal mode (#1912)
## Description

This PR fixes an issue where normal mode commands were being executed in
terminal mode buffers. The change ensures that the command `norm! zz` is
only executed if the buffer type is not "terminal". This prevents errors
when using Zen mode with terminal buffers.

## Related Issue(s)

- Fixes #1911

## Screenshots

<!-- Add screenshots of the changes if applicable. -->
2025-10-20 15:08:41 +02:00
Ori Perry
3f0fe34308
feat(image): allow specifying a page number for inlined pdfs (#1806)
## Description
Allow specifying a page number for pdfs inside of markdown.

This is done by adding "#page=<page-number>" to the file name. This is
same way it is done in obsidian (as discussed in
https://forum.obsidian.md/t/link-to-the-exact-page-of-and-external-pdf-file/2111)

The parsing of the page info should probably be done way before the
conversion, but this was the best I could with my limited time.
I'm pretty new to lua, and this codebase, so this might not be the best
code, but I hope it at least helps :D
## Related Issue(s)

  - Fixes #1805
2025-10-20 15:05:53 +02:00
Tod Morrison
441bdcd210
fix(image): correct off by one issue in render fallback (#1560)
Fix off-by-one issue in render_fallback when a tabline is shown (e.g.
with plugins like bufferline.nvim).

## Description

When a tabline is used/shown, the positioning in render_fallback is off
by one. This change checks whether a tabline would be shown and uses the
correct math for that case and, otherwise, works as before.

## Related Issue(s)

  - Fixes #1557
2025-10-20 14:59:33 +02:00
Jason Cheatham
231ffae08d
feat(debug): allow debug evaluation of block selections (#1331)
## Description

This PR adds basic support for visual block selections to
`Snacks.debug.run()`. This is useful when code doesn't start at the
beginning of a line, such as in comment blocks.

## Related Issue(s)

<!--
  If this PR fixes any issues, please link to the issue here.
  - Fixes #<issue_number>
-->

## Screenshots

<!-- Add screenshots of the changes if applicable. -->
<img width="271" alt="Screenshot 2025-02-19 at 23 02 35"
src="https://github.com/user-attachments/assets/5a440b32-6846-4345-b105-42e64796ac65"
/>
2025-10-20 14:53:55 +02:00
Folke Lemaitre
fe88a07d53
feat(dashboard): optional filter for projects. Closes #798 2025-10-20 14:48:06 +02:00
Folke Lemaitre
021e04fa6f
fix(picker): use nvim_paste instead of nvim_put. Closes #1941 2025-10-20 14:28:20 +02:00
Folke Lemaitre
5cda9532ca
fix(picker): allow some sources to use the current window as main. Closes #2012. See #1941 2025-10-20 14:28:20 +02:00
Franck Delage
e9228d6b2f
fix(dashboard): replace deprecated AutoSession command (#2288)
## Description

The command `SessionRestore` from the auto-session plugin is deprecated.
Replaced it with `AutoSession restore`.
2025-10-20 13:24:04 +02:00
Eric Wong
ca0858a30a
fix(picker.marks): fix buffer checking (#2287)
This buffer number index is 1.
2025-10-20 06:37:28 +02:00
Folke Lemaitre
fcd309f9ea
fix(dashboard): oldfiles filter should return a boolean instead of the result of find. Fixes #2283 2025-10-19 23:01:57 +02:00
Copilot
1ed737e465
fix(dashboard): recent_files section not displaying files without cwd parameter (#2284)
## Problem

The `recent_files` section in the dashboard was not displaying any files
when called without a `cwd` parameter, which is the default usage in
most dashboard examples and documentation.

```lua
-- This would show an empty section after the bug was introduced
{ section = "recent_files", limit = 8 }
```

## Root Cause

When `opts.cwd` was not provided, the code set `root = ""` (empty
string) and passed it to the oldfiles filter:

```lua
local root = opts.cwd and svim.fs.normalize(...) or ""
for file in M.oldfiles({ filter = { [root] = true } }) do
```

The filter logic in `M.oldfiles` checks if a file path starts with the
filter path **AND** if the character immediately after that prefix is a
directory separator (`/` or `\`). With an empty string as the filter
path:

1. `file:sub(1, 0) == ""` is always `true`
2. But `file:sub(1, 1):find("[/\\]")` is `false` for most files (unless
they start with `/` or `\`)
3. This results in `matches = false`, causing all files to be filtered
out

## Solution

Changed the logic to use `nil` instead of an empty string when no `cwd`
is specified:

```lua
local root = opts.cwd and svim.fs.normalize(opts.cwd == true and vim.fn.getcwd() or opts.cwd) or nil
-- Only filter by directory when root is specified. If nil, M.oldfiles will use default filters only (excludes stdpath data/cache/state).
local oldfiles_opts = root and { filter = { [root] = true } } or nil
local ret = {} ---@type snacks.dashboard.Section
for file in M.oldfiles(oldfiles_opts) do
```

When no filter is passed, `M.oldfiles()` uses only its default filters
(excluding stdpath data/cache/state directories), which is the intended
behavior for showing all recent files.

## Testing

All usage scenarios now work correctly:

| Scenario | Code | Behavior |
|----------|------|----------|
| No cwd | `{ section = "recent_files" }` |  Shows all recent files
(except stdpath) |
| Current dir | `{ section = "recent_files", cwd = true }` |  Shows
files in cwd |
| Specific dir | `{ section = "recent_files", cwd = "/path" }` |  Shows
files in specified path |

## Impact

This is a minimal, surgical fix (4 lines changed) that restores the
expected behavior documented in all dashboard examples without affecting
any other functionality.

Fixes the issue where users reported empty recent_files sections after
updating to the latest version.

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>bug: dashboard does not display "recent_files"
section</issue_title>
> <issue_description>### Did you check docs and existing issues?
> 
> - [x] I have read all the snacks.nvim docs
> - [x] I have updated the plugin to the latest version before
submitting this issue
> - [x] I have searched the existing issues of snacks.nvim
> - [x] I have searched the existing issues of plugins related to this
issue
> 
> ### Neovim version (nvim -v)
> 
> 0.11 
> 
> ### Operating system/version
> 
> arch linux
> 
> ### Describe the bug
> 
> after updating, snacks.dashboard stopped displaying the "recent_files"
section.
> Looking through the commit history, I found that commit `5c4365e` is
relevant to that section. Upon rolling the plugin back to one commit
prior to it (commit `a4de830`), the section displayed as normal.
> 
> ### Steps To Reproduce
> 
> update to latest commit
> 
> ### Expected Behavior
> 
> section "recent files" displayed as per the documentations
> 
> ### Repro
> 
> ```lua
> vim.env.LAZY_STDPATH = ".repro"
> load(vim.fn.system("curl -s
https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()
> 
> require("lazy.minit").repro({
>   spec = {
>     { "folke/snacks.nvim", opts = {} },
>     -- add any other plugins here
>   },
> })
> ```</issue_description>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> </comments>
> 


</details>

Fixes folke/snacks.nvim#2283

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 Share your feedback on Copilot coding agent for the chance to win a
$200 gift card! Click
[here](https://survey3.medallia.com/?EAHeSx-AP01bZqG0Ld9QLQ) to start
the survey.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: folke <292349+folke@users.noreply.github.com>
2025-10-19 22:17:03 +02:00
Folke Lemaitre
d6e34b158d
fix(explorer.watch): handle systems where fs_event doesn't return file names. Closes #2190. Closes #2032
Some checks are pending
CI / ci (push) Waiting to run
2025-10-19 12:13:21 +02:00
Jay Z
ef59af0ffc
fix(image): hover close in insert mode (#2215)
## Description

I'm not 100% sure if this is a bug or if it was intentional, but the
`return` seems to have been lost from a previous refactor
e35d6cd4 (diff-ff9a4f8a621887c466394f755193cc78a5e69e0e2e86f4e668662e1434d3611eL878).

When an image displays using float or hover, the image can block the
text even in insert mode. This makes editing really hard. Adding the
`return` can close the hover in insert mode.

## Related Issue(s)

I couldn't find an issue created for this, but there is a discussion
about it https://github.com/folke/snacks.nvim/discussions/1777.

## Screenshots

Before the fix, the image shows in insert mode.
<img width="704" height="710" alt="image"
src="https://github.com/user-attachments/assets/224883d1-edbc-4f7a-8c1b-91ef00dbe21e"
/>

After the fix, the image stops showing in insert mode.
<img width="389" height="127" alt="image"
src="https://github.com/user-attachments/assets/d704d4f8-9259-4e5e-b7a9-954ea6e2a788"
/>
2025-10-19 12:04:44 +02:00
Folke Lemaitre
65a5c8b3d0
fix(picker.grep): faulty rg cmd. Closes #2280 2025-10-19 11:30:35 +02:00
Folke Lemaitre
5c4365e993
fix(dashboard): recent cwd filter matching 2025-10-19 11:27:52 +02:00
Masayuki Izumi
057d4ab80e
fix(dashboard): fix path filtering for recent_files with cwd option (#2201)
## Description

Fix incorrect path filtering when using `recent_files` section with
`cwd`
option in dashboard.

Previously, when setting cwd to `/foo/bar/baz`, files from directories
with
the same prefix like `/foo/bar/bazbaz` were incorrectly included in the
recent
files list. This was due to simple string prefix matching without
considering
 directory boundaries.

The fix ensures proper directory boundary checking by verifying that the
path
either exactly matches the filter path or is followed by a "/"
character.

## Screenshots

```lua
return {
  "snacks.nvim",
  ---@type snacks.Config
  opts = {
    dashboard = {
      enabled = true,
      sections = {
        {
          title = "Recent Files " .. vim.uv.cwd(),
          section = "recent_files",
          cwd = true,
        },
      },
    },
  },
}
```

### before
<img width="659" height="149" alt="CleanShot 2025-09-24 at 00 00 13"
src="https://github.com/user-attachments/assets/943ad53f-11c5-49d2-b680-f032ad5fee94"
/>

### after
<img width="639" height="111" alt="CleanShot 2025-09-24 at 00 01 01"
src="https://github.com/user-attachments/assets/0dbde991-5164-4afa-9981-ae6707a8fcc0"
/>
2025-10-19 11:11:38 +02:00
Cameron Ring
6daef528c1
fix(notifier): include icon in padding in minimal style (#2239)
## Description

This prevents the text from running underneath the icon when the text is
a single line and the text plus padding is less than max_width.

It does not handle the case where the text is longer than max_width
(with or without wrap).

## Related Issue(s)

Fixes #2238 

## Screenshots

Before:

<img width="494" height="106" alt="Screenshot 2025-10-03 at 13 52 39"
src="https://github.com/user-attachments/assets/fde31ed5-e2ac-4ad3-8ac3-8f74f84456a7"
/>


After:

<img width="518" height="111" alt="Screenshot 2025-10-03 at 13 53 33"
src="https://github.com/user-attachments/assets/0eb72818-d151-40b9-9a0c-dd4d850abba4"
/>
2025-10-19 11:09:19 +02:00
Folke Lemaitre
24e92e0c94
fix(dashboard): use fqn for icon. Closes #1496 2025-10-19 11:07:53 +02:00
Frank Blendinger
98345c7012
fix(scratch): branch fallback for detached head (#1519)
## Description

I work a lot with detached `HEAD` in Git repos and noticed that the
scratch files for those were missing in `Snacks.scratch.select()`.

When working with a detached head, the `git branch --show-current`
returns an empty string, so ret will be `nil` in this case. This breaks
the scratch filename generation. The `table.concat` skips the `nil`
value, so the generated filename is missing one `|` separator. This will
later break in `M.list()`: `file_decode` and `match` will confuse
`branch` and `ft`, and the entry is not added to the items list.

A simple fix for this is to fallback to an empty string for the branch
name.

## Related Issue(s)

I didn't create an issue but fixed the problem right away. Hope this is
fine.

## Screenshots

I can provide one if requested.
2025-10-19 11:05:37 +02:00
Jozsef Lazar
3e9e2e2d71
feat(picker.projects): make max_depth customizable (#2253)
## Description

By making the `max_depth` customizable, I could provide a single entry
dir to the projects picker to discover all my repos 🤞
2025-10-19 11:00:37 +02:00
Folke Lemaitre
d05071255c
fix(picker.preview): directory preview should use cwd. Closes #2212. Fixes #2093 2025-10-19 10:58:26 +02:00