You can use
getline('.')[:col('.')-2] to find the string of characters before the current cursor position.
Note that you need
col('.')-2, first because
col(...) returns 1 for the first column, while the substring syntax is 0-based (therefore -1) and also because when slicing a string with
[start:end], the index for the
end is inclusive, so the byte at that index is included in the result (therefore another -1, totaling an adjustment of -2.)
Note also that this won't work in the first column, when
col('.') will return 1, so you might need to use a special handler for that case (for example, returning an empty string.)
At that point, you can use the
strcharpart() function to access a specific character by index, which will give you access to the last character of that part (which happens to be the character just before the cursor.)
To help you find the index of the last character, you can use the
strchars() function to find how many characters are in that string.
Putting it all together:
if col('.') <= 1
" Cursor is on the first column.
let before_cursor = getline('.')[:col('.')-2]
return strcharpart(before_cursor, strchars(before_cursor)-1)