8

I'm on a highlighted complex syntax element and would like to get it's content. Can you think of any way to do this?

Maybe there's some way to search for a regular expression so that it contains the cursor?

EDIT

Okay, example. The cursor is inside a string, and I want to get the text, the content of this syntactic element. Consider the following line:

String myString = "Foobar, [CURSOR]cool \"string\""; // And some other "rubbish"

I want to write a function that returns

"Foobar, cool \"string\""
blinry
  • 4,746
  • 4
  • 26
  • 31

4 Answers4

10

if I understood the question. I found this gem some time ago and don't remember where but i used to understand how syntax hilighting works in vim:

" Show syntax highlighting groups for word under cursor
nmap <leader>z :call <SID>SynStack()<CR>
function! <SID>SynStack()
  if !exists("*synstack")
    return
  endif
  echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')
endfunc
eolo999
  • 863
  • 6
  • 13
  • 1
    This is a good start, but it only gives me the names of the syntax groups. I need the content. – blinry Apr 29 '11 at 17:13
  • 1
    Can you please explain how can this be used ? I don't know much about vim `syntax` highlighting - but it seems like a gem but I don't its significance. :( – Yugal Jindle Dec 15 '13 at 17:19
  • 1
    Wonderfull !! `:echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')` – Tinmarino Jun 01 '19 at 20:17
4

The textobj-syntax plugin might help. It creates a custom text object, so that you can run viy to visually select the current syntax highlighted element. The plugin depends on the textobj-user plugin, which is a framework for creating custom text objects.

nelstrom
  • 18,802
  • 13
  • 54
  • 70
1

This is a good use for text objects (:help text-objects). To get the content you're looking for (Foobar, cool \"string\"), you can just do:

yi"

y = yank
i" = the text object "inner quoted string"

The yank command by default uses the unnamed register ("", see :help registers), so you can access the yanked contents programmatically using the getreg() function or the shorthand @{register-name}:

:echo 'String last yanked was:' getreg('"')
:echo 'String last yanked was:' @"

Or you can yank the contents into a different register:

"qyi"

yanks the inner quoted string into the "q register, so it doesn't conflict with standard register usage (and can be accessed as the @q variable).

benizi
  • 4,046
  • 5
  • 28
  • 25
  • 1
    Thanks, but that's not general enough. I didn't know that i" ignores escaped quotes, nice! – blinry Feb 08 '12 at 12:30
  • Because of the flexibility in how Vim syntax authors can specify language elements, you might have a hard time finding something that works as a general "inner syntactic element". – benizi Feb 08 '12 at 18:04
0

EDIT: Seeing that the plugin mentioned by nelstrom works similar to my original approach, I settled on this slightly more elegant solution:

fu s:OnLink()
    let stack = synstack(line("."), col("."))
    return !empty(stack)
endf

normal mc 

normal $
let lineLength = col(".")
normal `c

while col(".") > 1
    normal h
    if !s:OnLink()
        normal l
        break
    endif
endwhile
normal ma`c

while col(".") < lineLength
    normal l
    if !s:OnLink()
        normal h
        break
    endif
endwhile
normal mb`av`by
blinry
  • 4,746
  • 4
  • 26
  • 31
  • 1
    So your function scans to the left and right of the cursor position, and will stop when the syntax stack is empty. This way, you will however only capture a syntax element that is on one line, and you will have problems with neighbouring elements. – Zane Oct 28 '18 at 00:25