0

Problem:

I noticed that my "&packpath" has some duplicates, I want to remove them.

What I have tried:

My viml knowledge is not very strong but I did manage to create a unique "List", but I am not sure how to turn that list back into the correct string without calling "!awk/!sed/!perl", I now think that perhaps there is a simpler "vim" way to do it? my example:

let newpackpath = string(uniq(split(&packpath, ',')))

Returns this string:

['/data/data/com.termux/files/home/conf/nvim', 
'/data/data/com.termux/files/home/data/nvim/site', 
'/data/data/com.termux/files/usr/share/nvim/runtime', 
'/data/data/com.termux/files/usr/lib/nvim', 
'/data/data/com.termux/files/home/data/nvim/site/after', 
'/data/data/com.termux/files/home/conf/nvim/after']

To be correct, it should look like this instead:

/data/data/com.termux/files/home/conf/nvim,/data/data/com.termux/files/home/data/nvim/site,/data/data/com.termux/files/usr/share/nvim/runtime,/data/data/com.termux/files/usr/lib/nvim,/data/data/com.termux/files/home/data/nvim/site/after,/data/data/com.termux/files/home/conf/nvim/after

I'm now I'm out of my viml-depth! my only knowledge would be to use !awk/!perl/!sed somehow?!

can vim handle this itself???

either way....

How can I dedupe my "&packpath" or "&runtimepath"?

To those who can help, thank you!

1 Answer 1

4

packpath, the option

packpath is an option, which means it can be altered using the set command. The set command already does de-duplication for appending values. For example,

set packpath=a
set packpath+=dd
set packpath+=dd
set packpath+=dd
set packpath?

gives

 a,dd

It even adds/strips commas for you. It is not always possible, but if you can, use the set command.

Unfortunately, set only looks at new values added, and offers no way to fix an existing duplicate.

&packpath, the variable

vim offers a read/write variable "view" into this option using the & syntax. When using this you syntax, you don't get the de-duplication or comma addition. Thus,

let &packpath='a'
let &packpath+='b'
let &packpath+='b'
echo &packpath

gives

abb

your example

There are two issues here, first using uniq( only applies to sorted arrays, thus is not guaranteed to give you a unique array, and second string( does not join a string with commas.

let newpackpath = string(uniq(split(&packpath, ',')))

Instead,

let &packpath = join(uniq(sort(split(&packpath, ','))), ',')

or

let &packpath = &packpath->split(',')->sort()->uniq()->join(',')

are valid solutions, except that the order of packpath will be altered, which may or may not be what you want.

3
  • works perfectly! thank you @Mass, as for your last comment "except for the order of packpath will be altered", this is not what I want so I just removed sort() and its keeps the original order. thanks for a beautiful explanation!
    – 5c0tt
    Aug 28, 2021 at 22:09
  • 1
    @5c0tt, to emphasize, uniq( will only remove duplicates if they are directly successive. If that works in your use-case, great!
    – Mass
    Aug 28, 2021 at 22:32
  • Thank you once again! great catch!!! yes that is true in my case, so basically it is best to use uniq() along with sort() for succession, unless you are lucky enough that the dupes are in succession already! thanks @Mass for the amazing explanations, I really appreciate it!
    – 5c0tt
    Aug 29, 2021 at 13:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.