Skip to content

Improve :set += -= ^= to process items individually for comma-separated options#19783

Closed
h-east wants to merge 1 commit intovim:masterfrom
h-east:improve-comma-option-keyvalue-handling
Closed

Improve :set += -= ^= to process items individually for comma-separated options#19783
h-east wants to merge 1 commit intovim:masterfrom
h-east:improve-comma-option-keyvalue-handling

Conversation

@h-east
Copy link
Copy Markdown
Member

@h-east h-east commented Mar 21, 2026

For comma-separated options with P_COLON (e.g., diffopt, listchars,
fillchars), :set += -= ^= now processes each comma-separated item
individually instead of treating the whole value as a single string.

For :set += and :set ^=:

  • A "key:value" item where the key already exists with a different value:
    the old item is replaced.
  • An exact duplicate item is left unchanged.
  • A new item is appended (+=) or prepended (^=).

For :set -=:

  • A "key:value" or "key:" item removes by key match regardless of value.
  • A non-colon item removes by exact match.

This also handles multiple non-colon items (e.g., :set
diffopt-=filler,internal)
by processing each item individually, making the behavior
order-independent.

Previously, :set += simply appended the value, causing duplicate keys to
accumulate.

Fixes: #18495

@h-east h-east marked this pull request as draft March 21, 2026 19:55
@h-east h-east force-pushed the improve-comma-option-keyvalue-handling branch from 06d7f83 to 1e0960f Compare March 21, 2026 20:10
@h-east h-east marked this pull request as ready for review March 21, 2026 20:11
@h-east h-east force-pushed the improve-comma-option-keyvalue-handling branch from 1e0960f to 63e0b7b Compare March 21, 2026 20:28
Comment thread src/testdir/test_listchars.vim
@h-east h-east force-pushed the improve-comma-option-keyvalue-handling branch from 63e0b7b to 8b48753 Compare March 22, 2026 05:13
Comment thread src/option.c Outdated
@zeertzjq
Copy link
Copy Markdown
Member

There may be some inconsistency here. With the default diffopt=internal,filler,closeoff,indent-heuristic,inline:char:

  • :set diffopt-=filler,internal doesn't change the option value.
  • :set diffopt-=internal,filler changes it to closeoff,indent-heuristic,inline:char.
  • :set diffopt-=indent-heuristic,inline:char changes it to internal,filler,closeoff.
  • :set diffopt-=inline:char,indent-heuristic also changes it to internal,filler,closeoff.

I'm not sure if this is a problem, or if it's fine.

@vim-ml
Copy link
Copy Markdown

vim-ml commented Mar 22, 2026 via email

@h-east
Copy link
Copy Markdown
Member Author

h-east commented Mar 22, 2026

There may be some inconsistency here. With the default diffopt=internal,filler,closeoff,indent-heuristic,inline:char:

* `:set diffopt-=filler,internal` doesn't change the option value.

The above behavior is a bug. I am working on fixing it.
-->Done.

* `:set diffopt-=internal,filler` changes it to `closeoff,indent-heuristic,inline:char`.

The above results are correct, but the internal logic was flawed. I am currently working on fixing that as well.
-->Done.

* `:set diffopt-=indent-heuristic,inline:char` changes it to `internal,filler,closeoff`.

* `:set diffopt-=inline:char,indent-heuristic` also changes it to `internal,filler,closeoff`.

I'm not sure if this is a problem, or if it's fine.

The documentation for set+=, set^=, and set-= has been revised to reflect the changes made.
-->Done.
Thanks fot the reporting!

@h-east h-east changed the title Improve :set += -= ^= for comma-separated options with "key:value" items Improve :set += -= ^= to process items individually for comma-separated options Mar 22, 2026
…ed options

For comma-separated options with P_COLON (e.g., diffopt, listchars,
fillchars), :set += -= ^= now processes each comma-separated item
individually instead of treating the whole value as a single string.

For :set += and :set ^=:
- A "key:value" item where the key already exists with a different value:
  the old item is replaced.
- An exact duplicate item is left unchanged.
- A new item is appended (+=) or prepended (^=).

For :set -=:
- A "key:value" or "key:" item removes by key match regardless of value.
- A non-colon item removes by exact match.

This also handles multiple non-colon items (e.g., :set
diffopt-=filler,internal)
by processing each item individually, making the behavior
order-independent.

Previously, :set += simply appended the value, causing duplicate keys to
accumulate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@chrisbra
Copy link
Copy Markdown
Member

Thanks, that is a really nice improvement of the option handling.

@chrisbra chrisbra closed this in e2f4e18 Mar 22, 2026
@h-east h-east deleted the improve-comma-option-keyvalue-handling branch March 22, 2026 16:25
zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Mar 23, 2026
Problem:  Option handling for key:value suboptions is limited
Solution: Improve :set+=, :set-= and :set^= for options that use
          "key:value" pairs (Hirohito Higashi)

For comma-separated options with P_COLON (e.g., diffopt, listchars,
fillchars), :set += -= ^= now processes each comma-separated item
individually instead of treating the whole value as a single string.

For :set += and :set ^=:
- A "key:value" item where the key already exists with a different value:
  the old item is replaced.
- An exact duplicate item is left unchanged.
- A new item is appended (+=) or prepended (^=).

For :set -=:
- A "key:value" or "key:" item removes by key match regardless of value.
- A non-colon item removes by exact match.

This also handles multiple non-colon items (e.g., :set
diffopt-=filler,internal) by processing each item individually, making
the behavior order-independent.

Previously, :set += simply appended the value, causing duplicate keys to
accumulate.

fixes:  vim/vim#18495
closes: vim/vim#19783

vim/vim@e2f4e18

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Mar 23, 2026
Problem:  Option handling for key:value suboptions is limited
Solution: Improve :set+=, :set-= and :set^= for options that use
          "key:value" pairs (Hirohito Higashi)

For comma-separated options with P_COLON (e.g., diffopt, listchars,
fillchars), :set += -= ^= now processes each comma-separated item
individually instead of treating the whole value as a single string.

For :set += and :set ^=:
- A "key:value" item where the key already exists with a different value:
  the old item is replaced.
- An exact duplicate item is left unchanged.
- A new item is appended (+=) or prepended (^=).

For :set -=:
- A "key:value" or "key:" item removes by key match regardless of value.
- A non-colon item removes by exact match.

This also handles multiple non-colon items (e.g., :set
diffopt-=filler,internal) by processing each item individually, making
the behavior order-independent.

Previously, :set += simply appended the value, causing duplicate keys to
accumulate.

fixes:  vim/vim#18495
closes: vim/vim#19783

vim/vim@e2f4e18

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Mar 23, 2026
Problem:  Option handling for key:value suboptions is limited
Solution: Improve :set+=, :set-= and :set^= for options that use
          "key:value" pairs (Hirohito Higashi)

For comma-separated options with P_COLON (e.g., diffopt, listchars,
fillchars), :set += -= ^= now processes each comma-separated item
individually instead of treating the whole value as a single string.

For :set += and :set ^=:
- A "key:value" item where the key already exists with a different value:
  the old item is replaced.
- An exact duplicate item is left unchanged.
- A new item is appended (+=) or prepended (^=).

For :set -=:
- A "key:value" or "key:" item removes by key match regardless of value.
- A non-colon item removes by exact match.

This also handles multiple non-colon items (e.g., :set
diffopt-=filler,internal) by processing each item individually, making
the behavior order-independent.

Previously, :set += simply appended the value, causing duplicate keys to
accumulate.

fixes:  vim/vim#18495
closes: vim/vim#19783

vim/vim@e2f4e18

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
zeertzjq added a commit to neovim/neovim that referenced this pull request Mar 23, 2026
…ed (#38426)

Problem:  Option handling for key:value suboptions is limited
Solution: Improve :set+=, :set-= and :set^= for options that use
          "key:value" pairs (Hirohito Higashi)

For comma-separated options with P_COLON (e.g., diffopt, listchars,
fillchars), :set += -= ^= now processes each comma-separated item
individually instead of treating the whole value as a single string.

For :set += and :set ^=:
- A "key:value" item where the key already exists with a different value:
  the old item is replaced.
- An exact duplicate item is left unchanged.
- A new item is appended (+=) or prepended (^=).

For :set -=:
- A "key:value" or "key:" item removes by key match regardless of value.
- A non-colon item removes by exact match.

This also handles multiple non-colon items (e.g., :set
diffopt-=filler,internal) by processing each item individually, making
the behavior order-independent.

Previously, :set += simply appended the value, causing duplicate keys to
accumulate.

fixes:  vim/vim#18495
closes: vim/vim#19783

vim/vim@e2f4e18

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

set+= didnot clear prev option firstly

4 participants