import vim
import re
import json
from os import path


def get_entry_by_filename(entries, fn, key=None):
    """Search for an entry in entries where key(entry['file']) matches
    key(fn) and returns it. If key is None than file names are compared
    directly. Returns None if none is found."""

    if key is None:
        key = lambda x: x

    for e in entries:
        if key(fn) == key(e['file']):
            return e

    return None

def find_entry(entries, fn):
    """Find an entry that matches the given filename fn more or less."""

    entry = get_entry_by_filename(entries, curr_file)
    if entry is not None:
        return entry

    key = lambda fn: path.splitext(fn)[0]
    entry = get_entry_by_filename(entries, curr_file, key)
    if entry is not None:
        return entry

    key = lambda fn: path.basename(path.splitext(fn)[0])
    entry = get_entry_by_filename(entries, curr_file, key)
    if entry is not None:
        return entry

    return None


ccd = vim.eval("l:ccd")
with open(ccd) as database:
    entries = json.load(database)

    curr_file = vim.eval("expand('%:p')")
    entry = find_entry(entries, curr_file)

    if entry is not None:
        opts = []

        for result in re.finditer(r'-D\s*[^\s]+', entry['command']):
            opts.append(result.group(0))
        for result in re.finditer(r'-std\s*[^\s]+', entry['command']):
            opts.append(result.group(0))
        for result in re.finditer(r'-isystem\s*[^\s]+', entry['command']):
            opts.append(result.group(0))
        for result in re.finditer(r'-I\s*([^\s]+)', entry['command']):
            opts.append('-I' + path.join(entry['directory'], result.group(1)))

        vim.command("let l:clang_options = '" + ' '.join(opts) + "'")

@@ -975,212 +975,309 @@
 ne%0A%0A
-%0Accd = vim.eval(%22l:ccd%22)%0Awith open(ccd) as database:%0A    entries = json.load(database)%0A%0A    curr_file = vim.eval(%22expand('%25:p')%22)%0A    entry = find_entry(entries, curr_file)%0A%0A    if entry is not None:%0A    
+def parse_arguments(arguments_list, directory):%0A    match = re.compile(r'-(D%7CI%7Cstd%7Cisystem)%5Cs*(%5B%5E%5Cs%5D+)').match%0A    return %5Bx.group(0) if x.group(1) != 'I' else '-I' + path.join(directory, x.group(2))%0A            for x in map(match, arguments_list) if x%5D%0A%0Adef parse_command(command_string, directory):%0A
     
@@ -1287,20 +1287,16 @@
 s = %5B%5D%0A%0A
-    
     for 
@@ -1333,39 +1333,33 @@
 %5E%5Cs%5D+', 
-entry%5B'command'%5D):%0A    
+command_string):%0A
         
@@ -1379,36 +1379,32 @@
 esult.group(0))%0A
-    
     for result i
@@ -1435,39 +1435,33 @@
 %5E%5Cs%5D+', 
-entry%5B'command'%5D):%0A    
+command_string):%0A
         
@@ -1485,36 +1485,32 @@
 t.group(0))%0A    
-   
- 
 for result in re
@@ -1545,38 +1545,33 @@
 +', 
-entry%5B'command'%5D):%0A   
+command_string):%0A
         
  opt
@@ -1558,33 +1558,32 @@
 tring):%0A        
- 
 opts.append(resu
@@ -1595,20 +1595,16 @@
 oup(0))%0A
-    
     for 
@@ -1647,31 +1647,25 @@
 )', 
-entry%5B'command'%5D):%0A    
+command_string):%0A
     
@@ -1697,23 +1697,16 @@
 th.join(
-entry%5B'
 director
@@ -1706,18 +1706,16 @@
 irectory
-'%5D
 , result
@@ -1727,16 +1727,427 @@
 p(1)))%0A%0A
+    return opts%0A%0A%0Accd = vim.eval(%22l:ccd%22)%0Awith open(ccd) as database:%0A    entries = json.load(database)%0A%0A    curr_file = vim.eval(%22expand('%25:p')%22)%0A    entry = find_entry(entries, curr_file)%0A%0A    if entry is not None:%0A        if 'arguments' in entry:%0A            opts = parse_arguments(entry%5B'arguments'%5D, entry%5B'directory'%5D)%0A        else:%0A            opts = parse_command(entry%5B'command'%5D, entry%5B'directory'%5D)%0A%0A
         

Handle a 'arguments' key in a compilation database.