I need a vim shortcut to display all non-duplicate struct names in the file being edited. I have made this C program which does this, however I have to leave the editor and execute the program in bash and return back to editing.

Lets say the file being edited is linux/drivers/net/ethernet/smsc/smsc911x.c. The output should be like following:

 0. smsc911x_data
 1. smsc911x_ops
 2. smsc911x_platform_config
 3. phy_device
 4. mii_bus
 5. net_device
 6. napi_struct
 7. regulator_bulk_data
 8. clk
 9. platform_device
10. sk_buff
11. net_device_stats
12. netdev_hw_addr
13. sockaddr
14. ethtool_drvinfo
15. ethtool_eeprom
16. ethtool_ops
17. net_device_ops
18. resource
19. device_node
20. dev_pm_ops
21. of_device_id
22. platform_driver

EDIT: The Parse() vim routine defined in the answer posted below doesn't prints all the struct names. It's output:

0. clk
1. device_node
2. ethtool_drvinfo
3. ethtool_eeprom
4. mii_bus
5. napi_struct
6. net_device
7. netdev_hw_addr
8. phy_device
9. regulator_bulk_data
10. resource
11. sk_buff
12. smsc911x_data
13. smsc911x_platform_config
14. sockaddr

I guess its because it is not able to handle cases like struct { ... } name;

  • 1
    Can't you just run :!./find_structs %?
    – muru
    Jul 5, 2015 at 14:17
  • Yes, but i want it to be inside vim so that i can run other operations like jump to struct definition using ctags.
    – manav m-n
    Jul 5, 2015 at 14:21
  • 2
    A plugin like this one might be more convenient: majutsushi.github.io/tagbar
    – muru
    Jul 5, 2015 at 14:27
  • @muru: i would prefer a custom vim script than depending on an external plugin especially when you are running vim in an embedded environment.
    – manav m-n
    Jul 6, 2015 at 9:46
  • Did you try with some search/substitute/sort commands ?
    – nobe4
    Jul 8, 2015 at 13:55

3 Answers 3

:e smsc911x.c
:read !grep -o "struct [^ ;,)]\+" # | awk '{print $2}' | sort -u


  • grep -o: returns only the match chars (useful for multiple match on one line)
  • [^ ;,)]: remove characters non part of struct name
  • #: use alternate file (smsc911x.c in this case)

See this gets even more results than your program -once removed that numbered order that I don't know where it comes from-

diff --git 1/your_result 2/my_result
index 0bee24a..90d7ce4 100644
--- 1/your_result
+++ 2/my_result
@@ -1,9 +1,13 @@

Save this to a mapping or function if you feel you will use it from time to time


Here you are :

function! Parse()
  " keep only the struct definitions
  v/\v.*(\s|\()struct (\w+).*/d
  " keep only the names of the structs
  %s/\v.*(\s|\()struct (\w+).*/\2/
  " sort and keep non-duplicate lines
  %sort u
  " add line numbers
  %s/^/\=printf('%-d. ', line('.')-1)

On your file use it with :

:call Parse()

In the file you provided I didn't match as results as you (but I didn't found any smsc911x_data for example).

If you want detailed explanation about how I did just ask :)

  • 1
    Remove the semicolons from the beginning of the commands, that is invalid syntax. Jul 8, 2015 at 17:40
  • 2
    @EvergreenTree No, it's not invalid to have the : in vimscript. Vim just ignores it. You can have as many leading : as you want.
    – jamessan
    Jul 8, 2015 at 19:20
  • I didn't realize that. I always though it designated a one-liner that the user would type out manually. Interesting! Jul 8, 2015 at 19:23
  • I was confused because it worked, but I find it cleaner without
    – nobe4
    Jul 8, 2015 at 19:25
  • @Nobe4: Your function displays only 15 out of the 23 struct names shown in the question's example. It missed out the other 9 struct names.
    – manav m-n
    Jul 8, 2015 at 21:55

I'd still suggest using the program that you wrote. You can save its output to a scratch buffer and then use tag navigation. Something like (hat-tip to Nobe4):

function! Parse()
    let command = "%!/path/to/find_structs " . shellescape(expand('%'))
    " http://vim.wikia.com/wiki/Vim_buffer_FAQ 
    " (How is a scratch (temporary) buffer created?)
    setlocal buftype=nofile
    setlocal bufhidden=hide
    setlocal noswapfile
    set nobuflisted
    execute command

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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