1

UPDATE

As @Matt pointed out g:jsonTemplate is a list that needs to be copied. I originally thought that multiline strings were strings and overlooked the varible assignment detail after debugging. The doc for the mutiline string is :h let-heredoc.

There was another issue, unrelated to this question, that I solved thanks to @D. Ben Knoble's answer. I misunderstood the docs when trying to make the search pattern case sensitive and used a non-existant 'C' flag for substitute(), instead of prepending the search pattern arg with '\C' (and using single quotes). After reading 27.1 from :h usr_27, I realised that the cause was a forgotten setting in my .vimrc (set ignorecase).

Working solution:

function InsertJsonObj()
  let date = trim(system('date +"%T"'))
  let uuid = GetUUID()
  let copy = copy(g:jsonTemplate) " now using copy()
  "next 2 lines: substituted double quotes for single quotes, removed erroneous flag and prepended pat with \C to make it case sensitive.
  let copy[1] = substitute(copy[1], '\CUUID', uuid, '')
  let copy[2] = substitute(copy[2], '\CDATE', date, '')
  call append(line('.'), copy)
endfunction


ORIGINAL POST

The goal:

I want to insert a dynamically generated json string with 1) a unique UUID and 2) the date

The issue:

The function I made appends the same string every time I ':call InsertJsonObj()'

My understanding:

Well ... I don't understand. I have other functions that insert different json strings and each function produces a distinct UUID but every call of a function returns the same UUID (i.e. InsertA() will always return id = A1 and InsertB() will always return id = B1).

After replacing the date format to show the time I noticed that the string did change but only each time the vimrc is sourced (InsertA() now returns id = A2 and InsertB() return id = B2).

I don't understand why a function is only made once when the config is sourced but using :call calls the function when the command is executed. I tried reading ':h function' but nothing really jumped at me.

My questions:

What is the cause of the problem?

What doc page or paragraph should I be looking into here?

The functions:

function GetUUID()
  return trim(system('uuidgen')) "a script
endfunction

function InsertJsonObj()
  let date = trim(system('date +"%T"'))
  let uuid = GetUUID()
  "call append(line('.'), GetUUID()) "this line appends a different value every time
  let copy = g:jsonTemplate
  let copy[1] = substitute(copy[1], "UUID", uuid, "C")
  let copy[2] = substitute(copy[2], "DDDD", date, "C")
  call append(line('.'), copy)
endfunction

let g:jsonTemplate =<< END
{
"id": "UUID",
"date": ["DDDD"],
},
END

Bellow are some of the calls to one of the functions:

# some calls to :call InsertJsonObj() after editing and resourcing .vimrc
{
"id": "91fe667f-7caf-47e5-b650-da1bc7532d8c",
"date": ["15:21:59"],
},
{
"id": "950e3fef-f4f5-4b47-a684-c28a1b70b6e5",
"date": ["15:21:01"],
},
{
"id": "950e3fef-f4f5-4b47-a684-c28a1b70b6e5",
"date": ["15:21:01"],
},
{
"id": "bda591b6-c9cd-4093-8659-697738b191f4",
"date": ["Dec 09, 2022"],
},

# bellow GetUUID appended twice with ':call append(line('.'), GetUUID())'
c79011d8-2f01-41ef-adca-6e12b39e02df
6d265289-8e16-4848-a719-f5ff6897c4d3


# adding 'call append(line('.'), GetUUID())' to the function body produces a different UUID but the same template string
{
"id": "11eb069b-ed95-4e03-af70-aae2711f10a0",
"date": ["15:28:31"],
},
def19400-d01f-4b40-8594-52a6fdc668aa

{
"id": "11eb069b-ed95-4e03-af70-aae2711f10a0",
"date": ["15:28:31"],
},
8f1ab0c4-8d8a-404b-a62c-b8379094f2f5

1 Answer 1

2
let copy = g:jsonTemplate

Obviously, this looks very wrong, as "jsonTemplate" has a type of List. And simple assignment of a list doesn't make a new copy in VimScript (and also in many or even all(?) other languages). Use copy() function or similar stuff.

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.