function! parse#ini#from_file(file) let file = a:file if ! filereadable(file) throw "E484: Can't open file " . file endif return parse#ini#from_string(join(readfile(file), "\n")) endfunction function! parse#ini#from_string(string) let scanner = string#scanner(a:string) let data = {} let current_section = data while ! scanner.eos() call scanner.skip('\_s\+') if scanner.scan(';') != "" call scanner.skip_until('[\r\n]\+') elseif scanner.scan('\[\([^\]]\+\)\]') != "" let section_name = scanner.matches[1] let data[section_name] = {} let current_section = data[section_name] elseif scanner.scan('\([^=]\+\)\s*=\s*\(\%([\r\n]\@!.\)*\)') != "" let current_section[string#trim(scanner.matches[1])] \ = string#eval((scanner.matches[2])) endif endwhile return data endfunction function! parse#ini#to_file(hash, file) call writefile(split(parse#ini#to_string(a:hash), "\n"), a:file) endfunction function! parse#ini#to_string(hash) let hash = a:hash let head = '' let body = '' if type(hash) != type({}) throw 'Expected Dictionary but given ' . variable#type_to_string(hash) endif for [section, values] in items(hash) if type(values) == type({}) let body .= '[' . section . "]\n" for [name, val] in items(values) let body .= name . ' = ' . string#to_string(val) . "\n" unlet val endfor elseif type(values) == type([]) " what now?! else let head .= section . ' = ' . string#to_string(values) . "\n" endif unlet values endfor return head . body endfunction