first commit.

This commit is contained in:
manga_osyo
2014-07-31 12:23:32 +09:00
commit 6a28e40ea9
12 changed files with 1541 additions and 0 deletions

40
README.md Normal file
View File

@@ -0,0 +1,40 @@
#brightest.vim
カーソル下の単語を移動するたびにハイライトする。
## Screencapture
![brightest](https://cloud.githubusercontent.com/assets/214488/3297888/eb37a8dc-f5f9-11e3-8620-5876f030d762.gif)
## Using
```vim
" ハイライトを有効にします(既定値)
BrightestEnable
" ハイライトを無効にします
BrightestDisable
" ハイライトするグループ名を設定します
let g:brightest_highlight = {
\ "group" : "Search"
\}
" ハイライトする単語のパターンを設定します
" デフォルト(空の文字列の場合)は <cword> が使用されます
let g:brightest_pattern = '\k\+'
" filetype=cpp を無効にする
let g:brightest#enable_filetypes = {
\ "cpp" : 0
\}
" filetype=vim のみを有効にする
let g:brightest#enable_filetypes = {
\ "_" : 0
\ "vim" : 1
\}
```

96
autoload/brightest.vim Normal file
View File

@@ -0,0 +1,96 @@
scriptencoding utf-8
let s:save_cpo = &cpo
set cpo&vim
let s:V = vital#of("brightest")
let s:Prelude = s:V.import("Prelude")
let s:Buffer = s:V.import("Coaster.Buffer")
let s:Highlight = s:V.import("Coaster.Highlight")
let s:Search = s:V.import("Coaster.Search")
let g:brightest#enable_filetypes = get(g:, "brightest#enable_filetypes", {})
" let g:brightest#highlight_format = get(g:, "brightest#highlight_format", "\\<%s\\>")
function! s:is_enable_in_current()
let default = get(g:brightest#enable_filetypes, "_", 1)
return g:brightest_enable && get(g:brightest#enable_filetypes, &filetype, default)
endfunction
function! brightest#hl_clear()
call s:Highlight.clear("cursor_word")
call s:Highlight.clear("cursor_line")
call s:Highlight.clear("current_word")
endfunction
function! s:highlight(name, pattern, hi)
if empty(a:hi) || empty(a:pattern) || a:hi.group == ""
return
endif
let pattern = printf(a:hi.format, a:pattern)
call s:Highlight.highlight(a:name, a:hi.group, pattern, a:hi.priority)
endfunction
function! s:single_word(pattern, highlight, cursorline)
let pattern = a:pattern
if pattern ==# ""
let word = expand("<cword>")
else
let word = s:Buffer.get_text_from_pattern(pattern)
endif
" マルチバイト文字はハイライトしない
if word == ""
\ || !empty(filter(split(word, '\zs'), "strlen(v:val) > 1"))
return
endif
let pattern = s:Prelude.escape_pattern(word)
call s:highlight("cursor_word", pattern, a:highlight)
call s:highlight("cursor_line", '\%' . line('.') . 'l' . pattern, a:cursorline)
endfunction
" function! s:with_current(current_group, group, pattern)
" let [first, last] = s:Search.region(a:pattern, "Wncb", "Wnce")
" if first == [0, 0] || last == [0, 0]
" return
" endif
" let word = s:Buffer.get_text_from_region([0] + first + [0], [0] + last + [0], "v")
" if word !~ '^' . a:pattern . '$'
" return
" endif
" let current = s:Search.pattern_by_range("v", first, last)
"
" " マルチバイト文字はハイライトしない
" if !empty(filter(split(word, '\zs'), "strlen(v:val) > 1"))
" return
" endif
"
" let pattern = printf(g:brightest#highlight_format, s:Prelude.escape_pattern(word))
"
" call s:Highlight.highlight("cursor_word", a:group, pattern, -1)
" call s:Highlight.highlight("current_word", a:current_group, current, -1)
" endfunction
function! brightest#highlight(pattern, highlight, cursorline, ...)
call brightest#hl_clear()
if !s:is_enable_in_current()
return
endif
if get(a:, 1, "") == ""
return s:single_word(a:pattern, a:highlight, a:cursorline)
else
return s:with_current(a:1, a:group, a:pattern)
endif
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo

12
autoload/vital.vim Normal file
View File

@@ -0,0 +1,12 @@
function! vital#of(name)
let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital')
let file = split(files, "\n")
if empty(file)
throw 'vital: version file not found: ' . a:name
endif
let ver = readfile(file[0], 'b')
if empty(ver)
throw 'vital: invalid version file: ' . a:name
endif
return vital#_{substitute(ver[0], '\W', '', 'g')}#new()
endfunction

View File

@@ -0,0 +1,304 @@
let s:self_version = expand('<sfile>:t:r')
" Note: The extra argument to globpath() was added in Patch 7.2.051.
let s:globpath_third_arg = v:version > 702 || v:version == 702 && has('patch51')
let s:loaded = {}
function! s:import(name, ...)
let target = {}
let functions = []
for a in a:000
if type(a) == type({})
let target = a
elseif type(a) == type([])
let functions = a
endif
unlet a
endfor
let module = s:_import(a:name)
if empty(functions)
call extend(target, module, 'keep')
else
for f in functions
if has_key(module, f) && !has_key(target, f)
let target[f] = module[f]
endif
endfor
endif
return target
endfunction
function! s:load(...) dict
for arg in a:000
let [name; as] = type(arg) == type([]) ? arg[: 1] : [arg, arg]
let target = split(join(as, ''), '\W\+')
let dict = self
while 1 <= len(target)
let ns = remove(target, 0)
if !has_key(dict, ns)
let dict[ns] = {}
endif
if type(dict[ns]) == type({})
let dict = dict[ns]
else
unlet dict
break
endif
endwhile
if exists('dict')
call extend(dict, s:_import(name))
endif
unlet arg
endfor
return self
endfunction
function! s:unload()
let s:loaded = {}
endfunction
function! s:exists(name)
return s:_get_module_path(a:name) !=# ''
endfunction
function! s:search(pattern)
let paths = s:_vital_files(a:pattern)
let modules = sort(map(paths, 's:_file2module(v:val)'))
return s:_uniq(modules)
endfunction
function! s:expand_modules(entry, all)
if type(a:entry) == type([])
let candidates = s:_concat(map(copy(a:entry), 's:search(v:val)'))
if empty(candidates)
throw printf('vital: Any of module %s is not found', string(a:entry))
endif
if eval(join(map(copy(candidates), 'has_key(a:all, v:val)'), '+'))
let modules = []
else
let modules = [candidates[0]]
endif
else
let modules = s:search(a:entry)
if empty(modules)
throw printf('vital: Module %s is not found', a:entry)
endif
endif
call filter(modules, '!has_key(a:all, v:val)')
for module in modules
let a:all[module] = 1
endfor
return modules
endfunction
function! s:_import(name)
if type(a:name) == type(0)
return s:_build_module(a:name)
endif
let path = s:_get_module_path(a:name)
if path ==# ''
throw 'vital: module not found: ' . a:name
endif
let sid = s:_get_sid_by_script(path)
if !sid
try
execute 'source' fnameescape(path)
catch /^Vim\%((\a\+)\)\?:E484/
throw 'vital: module not found: ' . a:name
catch /^Vim\%((\a\+)\)\?:E127/
" Ignore.
endtry
let sid = s:_get_sid_by_script(path)
endif
return s:_build_module(sid)
endfunction
function! s:_get_module_path(name)
if s:_is_absolute_path(a:name) && filereadable(a:name)
return a:name
endif
if a:name ==# ''
let paths = [s:self_file]
elseif a:name =~# '\v^\u\w*%(\.\u\w*)*$'
let paths = s:_vital_files(a:name)
else
throw 'vital: Invalid module name: ' . a:name
endif
call filter(paths, 'filereadable(expand(v:val))')
let path = get(paths, 0, '')
return path !=# '' ? path : ''
endfunction
function! s:_get_sid_by_script(path)
let path = s:_unify_path(a:path)
for line in filter(split(s:_redir('scriptnames'), "\n"),
\ 'stridx(v:val, s:self_version) > 0')
let list = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$')
if !empty(list) && s:_unify_path(list[2]) ==# path
return list[1] - 0
endif
endfor
return 0
endfunction
function! s:_file2module(file)
let filename = fnamemodify(a:file, ':p:gs?[\\/]\+?/?')
let tail = matchstr(filename, 'autoload/vital/_\w\+/\zs.*\ze\.vim$')
return join(split(tail, '[\\/]\+'), '.')
endfunction
if filereadable(expand('<sfile>:r') . '.VIM')
" resolve() is slow, so we cache results.
let s:_unify_path_cache = {}
" Note: On windows, vim can't expand path names from 8.3 formats.
" So if getting full path via <sfile> and $HOME was set as 8.3 format,
" vital load duplicated scripts. Below's :~ avoid this issue.
function! s:_unify_path(path)
if has_key(s:_unify_path_cache, a:path)
return s:_unify_path_cache[a:path]
endif
let value = tolower(fnamemodify(resolve(fnamemodify(
\ a:path, ':p')), ':~:gs?[\\/]\+?/?'))
let s:_unify_path_cache[a:path] = value
return value
endfunction
else
function! s:_unify_path(path)
return resolve(fnamemodify(a:path, ':p:gs?[\\/]\+?/?'))
endfunction
endif
if s:globpath_third_arg
function! s:_runtime_files(path)
return split(globpath(&runtimepath, a:path, 1), "\n")
endfunction
else
function! s:_runtime_files(path)
return split(globpath(&runtimepath, a:path), "\n")
endfunction
endif
let s:_vital_files_cache_runtimepath = ''
let s:_vital_files_cache = []
function! s:_vital_files(pattern)
if s:_vital_files_cache_runtimepath !=# &runtimepath
let path = printf('autoload/vital/%s/**/*.vim', s:self_version)
let s:_vital_files_cache = s:_runtime_files(path)
let mod = ':p:gs?[\\/]\+?/?'
call map(s:_vital_files_cache, 'fnamemodify(v:val, mod)')
let s:_vital_files_cache_runtimepath = &runtimepath
endif
let target = substitute(a:pattern, '\.', '/', 'g')
let target = substitute(target, '\*', '[^/]*', 'g')
let regexp = printf('autoload/vital/%s/%s.vim', s:self_version, target)
return filter(copy(s:_vital_files_cache), 'v:val =~# regexp')
endfunction
" Copy from System.Filepath
if has('win16') || has('win32') || has('win64')
function! s:_is_absolute_path(path)
return a:path =~? '^[a-z]:[/\\]'
endfunction
else
function! s:_is_absolute_path(path)
return a:path[0] ==# '/'
endfunction
endif
function! s:_build_module(sid)
if has_key(s:loaded, a:sid)
return copy(s:loaded[a:sid])
endif
let functions = s:_get_functions(a:sid)
let prefix = '<SNR>' . a:sid . '_'
let module = {}
for func in functions
let module[func] = function(prefix . func)
endfor
if has_key(module, '_vital_loaded')
let V = vital#{s:self_version}#new()
if has_key(module, '_vital_depends')
let all = {}
let modules =
\ s:_concat(map(module._vital_depends(),
\ 's:expand_modules(v:val, all)'))
call call(V.load, modules, V)
endif
try
call module._vital_loaded(V)
catch
" FIXME: Show an error message for debug.
endtry
endif
if !get(g:, 'vital_debug', 0)
call filter(module, 'v:key =~# "^\\a"')
endif
let s:loaded[a:sid] = module
return copy(module)
endfunction
if exists('+regexpengine')
function! s:_get_functions(sid)
let funcs = s:_redir(printf("function /\\%%#=2^\<SNR>%d_", a:sid))
let map_pat = '<SNR>' . a:sid . '_\zs\w\+'
return map(split(funcs, "\n"), 'matchstr(v:val, map_pat)')
endfunction
else
function! s:_get_functions(sid)
let prefix = '<SNR>' . a:sid . '_'
let funcs = s:_redir('function')
let filter_pat = '^\s*function ' . prefix
let map_pat = prefix . '\zs\w\+'
return map(filter(split(funcs, "\n"),
\ 'stridx(v:val, prefix) > 0 && v:val =~# filter_pat'),
\ 'matchstr(v:val, map_pat)')
endfunction
endif
if exists('*uniq')
function! s:_uniq(list)
return uniq(a:list)
endfunction
else
function! s:_uniq(list)
let i = len(a:list) - 1
while 0 < i
if a:list[i] ==# a:list[i - 1]
call remove(a:list, i)
let i -= 2
else
let i -= 1
endif
endwhile
return a:list
endfunction
endif
function! s:_concat(lists)
let result_list = []
for list in a:lists
let result_list += list
endfor
return result_list
endfunction
function! s:_redir(cmd)
let [save_verbose, save_verbosefile] = [&verbose, &verbosefile]
set verbose=0 verbosefile=
redir => res
silent! execute a:cmd
redir END
let [&verbose, &verbosefile] = [save_verbose, save_verbosefile]
return res
endfunction
function! vital#{s:self_version}#new()
return s:_import('')
endfunction
let s:self_file = s:_unify_path(expand('<sfile>'))

View File

@@ -0,0 +1,9 @@
scriptencoding utf-8
let s:save_cpo = &cpo
set cpo&vim
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@@ -0,0 +1,264 @@
scriptencoding utf-8
let s:save_cpo = &cpo
set cpo&vim
function! s:_vital_loaded(V)
let s:V = a:V
let s:Search = a:V.import("Coaster.Search")
endfunction
function! s:_vital_depends()
return [
\ "Coaster.Search"
\ ]
endfunction
" a <= b
function! s:pos_less_equal(a, b)
return a:a[0] == a:b[0] ? a:a[1] <= a:b[1] : a:a[0] <= a:b[0]
endfunction
function! s:as_wise_key(name)
return a:name ==# "char" ? "v"
\ : a:name ==# "line" ? "V"
\ : a:name ==# "block" ? "\<C-v>"
\ : a:name
endfunction
function! s:get_text_from_latest_yank(...)
if mode() != "n"
return
endif
let wise = get(a:, 1, "v")
let register = v:register == "" ? '"' : v:register
let old_selection = &selection
let &selection = 'inclusive'
let old_pos = getpos(".")
let old_reg = getreg(register)
try
execute printf('silent normal! `[%s`]y', wise)
return getreg(register)
finally
let &selection = old_selection
call setreg(register, old_reg)
call cursor(old_pos[1], old_pos[2])
endtry
endfunction
function! s:get_line_from_pos(pos)
return a:pos[0] == 0 ? getline(a:pos[1]) : getbufline(a:pos[0], a:pos[1])
endfunction
function! s:get_line_from_region(first, last)
if type(a:first) == type(0)
return s:get_line_from_region([0, a:first, 0, 0], a:last)
elseif type(a:last) == type(0)
return s:get_line_from_region(a:first, [0, a:last, 0, 0])
endif
if a:first[0] != 0 && a:first[0] == a:last[0]
return join(getbufline(a:first[0], a:first[1], a:last[1]), "\n")
endif
return join(getline(a:first[1], a:last[1]), "\n")
endfunction
function! s:yank(wise, first, last)
let old_view = winsaveview()
let old_selection = &selection
let &selection = 'inclusive'
let old_first = getpos("'[")
let old_last = getpos("']")
let old_pos = getpos(".")
try
call setpos("'[", a:first)
call setpos("']", a:last)
execute "normal! `[" . a:wise . "`]y"
finally
call setpos("'[", old_first)
call setpos("']", old_last)
let &selection = old_selection
call winrestview(old_view)
call setpos(".", old_pos)
endtry
endfunction
function! s:paste(wise, first, last, register)
let old_view = winsaveview()
let old_selection = &selection
let &selection = 'inclusive'
let old_first = getpos("'[")
let old_last = getpos("']")
let old_pos = getpos(".")
try
call setpos("'[", a:first)
call setpos("']", a:last)
execute printf('normal! `[%s`]"%sp', a:wise, a:register)
finally
call setpos("'[", old_first)
call setpos("']", old_last)
let &selection = old_selection
call winrestview(old_view)
call setpos(".", old_pos)
endtry
endfunction
function! s:get_text_line_from_lnum(first, last)
return join(getline(a:first, a:last), "\n")
endfunction
"
"
" function! s:get_text_line_from_region(first, last)
" " if type(a:first) == type([])
" " return s:get_text_line_from_region(a:first[1], a:last)
" " elseif type(a:last) == type([])
" " return s:get_text_line_from_region(a:first, a:last[1])
" " endif
" " return join(getline(a:first, a:last), "\n")
"
" return s:get_text_line_from_lnum(a:first[1], a:last[1])
" endfunction
function! s:get_char_from_region(first, last)
if a:first[1] == a:last[1]
return getline(a:first[1])[a:first[2] - 1 : a:last[2] - 1]
elseif (a:last[1] - a:first[1]) == 1
return getline(a:first[1])[ a:first[2] - 1 : ] . "\n"
\ . getline(a:last[1])[ : a:last[2] - 1]
else
return getline(a:first[1])[ a:first[2] - 1 : ] . "\n"
\ . s:get_text_line_from_lnum(a:first[1] + 1, a:last[1] - 1) . "\n"
\ . getline(a:last[1])[ : a:last[2] - 1]
endif
endfunction
function! s:get_block_from_region(first, last)
let first = a:first
let last = a:last
echo join(map(range(a:first[1], a:last[1]), "
\ s:get_char_from_region([first[0], v:val, first[2], first[3]], [last[0], v:val, last[2], last[3]])
\ "), "\n")
endfunction
function! s:get_text_from_region(first, last, ...)
let wise = get(a:, 1, "v")
if wise ==# "v"
return s:get_char_from_region(a:first, a:last)
elseif wise ==# "V"
return s:get_line_from_region(a:first, a:last)
elseif wise ==# "\<C-v>"
return s:get_block_from_region(a:first, a:last)
endif
" let old_first = getpos("'[")
" let old_last = getpos("']")
" try
" call setpos("'[", a:first)
" call setpos("']", a:last)
" return s:get_text_from_latest_yank(wise)
" finally
" call setpos("'[", old_first)
" call setpos("']", old_last)
" endtry
endfunction
function! s:get_text_from_pattern(pattern)
let [first, last] = s:Search.region(a:pattern, "Wncb", "Wnce")
if first == [0, 0]
return ""
endif
if last == [0, 0]
return ""
endif
let result = s:get_text_from_region([0] + first + [0], [0] + last + [0], "v")
if result !~ '^' . a:pattern . '$'
return ""
endif
return result
endfunction
function! s:_as_config(config)
let default = {
\ "textobj" : "",
\ "is_cursor_in" : 0,
\ "noremap" : 0,
\ }
let config
\ = type(a:config) == type("") ? { "textobj" : a:config }
\ : type(a:config) == type({}) ? a:config
\ : {}
return extend(default, config)
endfunction
let s:region = []
let s:wise = ""
function! s:_buffer_region_operator(wise)
let reg_save = @@
let s:wise = a:wise
let s:region = [getpos("'[")[1:], getpos("']")[1:]]
let @@ = reg_save
endfunction
nnoremap <silent> <Plug>(vital-coaster_buffer_region)
\ :<C-u>set operatorfunc=<SID>_buffer_region_operator<CR>g@
function! s:get_region_from_textobj(textobj)
let s:region = []
let config = s:_as_config(a:textobj)
let winview = winsaveview()
let pos = getpos(".")
try
silent execute (config.noremap ? 'onoremap' : 'omap') '<expr>'
\ '<Plug>(vital-coaster_buffer_region-target)' string(config.textobj)
let tmp = &operatorfunc
silent execute "normal \<Plug>(vital-coaster_buffer_region)\<Plug>(vital-coaster_buffer_region-target)"
let &operatorfunc = tmp
if !empty(s:region) && !s:pos_less_equal(s:region[0], s:region[1])
return ["", []]
endif
if !empty(s:region) && config.is_cursor_in && (s:pos_less(pos[1:], s:region[0]) || s:pos_less(s:region[1], pos[1:]))
return ["", []]
endif
return deepcopy([s:wise, s:region])
finally
call winrestview(winview)
call cursor(pos[1], pos[2])
endtry
endfunction
function! s:execute(expr, cmd)
let bufnr = bufnr("%")
try
noautocmd execute "bufdo if bufnr('%') == " a:expr . ' | ' . a:cmd . ' | endif'
finally
execute "buffer" bufnr
endtry
endfunction
function! s:setbufline(expr, lnum, text)
return s:execute(a:expr, "call setline(" . a:lnum . "," . string(a:text) . ")")
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@@ -0,0 +1,160 @@
scriptencoding utf-8
let s:save_cpo = &cpo
set cpo&vim
let s:base = {
\ "variables" : {
\ "hl_list" : {},
\ "id_list" : {}
\ }
\}
function! s:base.add(name, group, pattern, ...)
call self.delete(a:name)
let priority = get(a:, 1, 10)
let self.variables.hl_list[a:name] = {
\ "group" : a:group,
\ "pattern" : a:pattern,
\ "priority" : priority,
\ }
endfunction
function! s:base.is_added(name)
return has_key(self.variables.hl_list, a:name)
endfunction
function! s:base.hl_list()
return keys(self.variables.hl_list)
endfunction
function! s:base.enable_list(...)
let bufnr = get(a:, 1, bufnr("%"))
return keys(get(self.variables.id_list, bufnr, {}))
endfunction
function! s:base.delete(name)
if !self.is_added(a:name)
return -1
endif
unlet! self.variables.hl_list[a:name]
endfunction
function! s:base.delete_by(expr)
for [name, _] in items(self.variables.hl_list)
let group = _.group
let pattern = _.pattern
let priority = _.priority
if eval(a:expr)
call self.delete(name)
endif
endfor
endfunction
function! s:base.delete_all()
for name in self.hl_list()
call self.delete(name)
endfor
endfunction
function! s:base.get_hl_id(name, ...)
let bufnr = get(a:, 1, bufnr("%"))
return get(get(self.variables.id_list, bufnr, {}), a:name, "")
endfunction
function! s:base.is_enabled(name, ...)
let bufnr = get(a:, 1, bufnr("%"))
return self.get_hl_id(a:name, bufnr) != ""
endfunction
function! s:base.enable(name)
let hl = get(self.variables.hl_list, a:name, {})
if empty(hl)
return -1
endif
if self.is_enabled(a:name)
call self.disable(a:name)
endif
if !has_key(self.variables.id_list, bufnr("%"))
let self.variables.id_list[bufnr("%")] = {}
endif
let self.variables.id_list[bufnr("%")][a:name] = matchadd(hl.group, hl.pattern, hl.priority)
endfunction
function! s:base.enable_all()
for name in self.hl_list()
call self.enable(name)
endfor
endfunction
function! s:base.disable(name)
if !self.is_enabled(a:name)
return -1
endif
let id = -1
silent! let id = matchdelete(self.get_hl_id(a:name))
if id == -1
return -1
endif
let bufnr = bufnr("%")
unlet! self.variables.id_list[bufnr][a:name]
endfunction
function! s:base.disable_all()
for name in self.enable_list()
call self.disable(name)
endfor
endfunction
function! s:base.highlight(name, group, pattern, ...)
let priority = get(a:, 1, 10)
call self.add(a:name, a:group, a:pattern, priority)
call self.enable(a:name)
endfunction
function! s:base.clear(name)
call self.disable(a:name)
call self.delete(a:name)
endfunction
function! s:base.clear_all()
call self.disable_all()
call self.delete_all()
endfunction
function! s:make()
let result = deepcopy(s:base)
return result
endfunction
let s:global = s:make()
let s:funcs = keys(filter(copy(s:global), "type(v:val) == type(function('tr'))"))
for s:name in s:funcs
execute
\ "function! s:" . s:name . "(...) \n"
\ "return call(s:global." . s:name . ", a:000, s:global) \n"
\ "endfunction"
endfor
unlet s:name
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@@ -0,0 +1,62 @@
scriptencoding utf-8
let s:save_cpo = &cpo
set cpo&vim
function! s:_vital_loaded(V)
let s:V = a:V
let s:Buffer = s:V.import("Coaster.Buffer")
endfunction
function! s:_vital_depends()
return [
\ ]
endfunction
function! s:region(pattern, ...)
let flag_first = get(a:, 1, "")
let flag_last = get(a:, 2, "")
return [searchpos(a:pattern, flag_first), searchpos(a:pattern, flag_last)]
endfunction
function! s:region_pair(fist, last, ...)
" todo
endfunction
function! s:pattern_in_range(wise, first, last, pattern)
if a:first == a:last
return printf('\%%%dl\%%%dc', a:first[0], a:first[1])
elseif a:first[0] == a:last[0]
return printf('\%%%dl\%%>%dc%s\%%<%dc', a:first[0], a:first[1]-1, a:pattern, a:last[1]+1)
elseif a:last[0] - a:first[0] == 1
return printf('\%%%dl%s\%%>%dc', a:first[0], a:pattern, a:first[1]-1)
\ . "\\|" . printf('\%%%dl%s\%%<%dc', a:last[0], a:pattern, a:last[1]+1)
else
return printf('\%%%dl%s\%%>%dc', a:first[0], a:pattern, a:first[1]-1)
\ . "\\|" . printf('\%%>%dl%s\%%<%dl', a:first[0], a:pattern, a:last[0])
\ . "\\|" . printf('\%%%dl%s\%%<%dc', a:last[0], a:pattern, a:last[1]+1)
endif
endfunction
function! s:pattern_by_range(wise, first, last)
return s:pattern_in_range(a:wise, a:first, a:last, '.\{-}')
endfunction
function! s:text_by_pattern(pattern, ...)
let flag = get(a:, 1, "")
let [first, last] = s:region(a:pattern, "c" . flag, "ce" . flag)
if first == [0, 0] || last == [0, 0]
endif
let result = s:Buffer.get_text_from_region([0] + first + [0], [0] + last + [0], "v")
return result
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@@ -0,0 +1,385 @@
let s:save_cpo = &cpo
set cpo&vim
if v:version ># 703 ||
\ (v:version is 703 && has('patch465'))
function! s:glob(expr)
return glob(a:expr, 1, 1)
endfunction
else
function! s:glob(expr)
let R = glob(a:expr, 1)
return split(R, '\n')
endfunction
endif
function! s:globpath(path, expr)
let R = globpath(a:path, a:expr, 1)
return split(R, '\n')
endfunction
" Wrapper functions for type().
let [
\ s:__TYPE_NUMBER,
\ s:__TYPE_STRING,
\ s:__TYPE_FUNCREF,
\ s:__TYPE_LIST,
\ s:__TYPE_DICT,
\ s:__TYPE_FLOAT] = [
\ type(3),
\ type(""),
\ type(function('tr')),
\ type([]),
\ type({}),
\ has('float') ? type(str2float('0')) : -1]
" __TYPE_FLOAT = -1 when -float
" This doesn't match to anything.
" Number or Float
function! s:is_numeric(Value)
let _ = type(a:Value)
return _ ==# s:__TYPE_NUMBER
\ || _ ==# s:__TYPE_FLOAT
endfunction
" Number
function! s:is_number(Value)
return type(a:Value) ==# s:__TYPE_NUMBER
endfunction
" Float
function! s:is_float(Value)
return type(a:Value) ==# s:__TYPE_FLOAT
endfunction
" String
function! s:is_string(Value)
return type(a:Value) ==# s:__TYPE_STRING
endfunction
" Funcref
function! s:is_funcref(Value)
return type(a:Value) ==# s:__TYPE_FUNCREF
endfunction
" List
function! s:is_list(Value)
return type(a:Value) ==# s:__TYPE_LIST
endfunction
" Dictionary
function! s:is_dict(Value)
return type(a:Value) ==# s:__TYPE_DICT
endfunction
function! s:truncate_smart(str, max, footer_width, separator)
echoerr 'Prelude.truncate_smart() is obsolete. Use its truncate_skipping() instead; they are equivalent.'
return s:truncate_skipping(a:str, a:max, a:footer_width, a:separator)
endfunction
function! s:truncate_skipping(str, max, footer_width, separator)
let width = s:wcswidth(a:str)
if width <= a:max
let ret = a:str
else
let header_width = a:max - s:wcswidth(a:separator) - a:footer_width
let ret = s:strwidthpart(a:str, header_width) . a:separator
\ . s:strwidthpart_reverse(a:str, a:footer_width)
endif
return s:truncate(ret, a:max)
endfunction
function! s:truncate(str, width)
" Original function is from mattn.
" http://github.com/mattn/googlereader-vim/tree/master
if a:str =~# '^[\x00-\x7f]*$'
return len(a:str) < a:width ?
\ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width)
endif
let ret = a:str
let width = s:wcswidth(a:str)
if width > a:width
let ret = s:strwidthpart(ret, a:width)
let width = s:wcswidth(ret)
endif
if width < a:width
let ret .= repeat(' ', a:width - width)
endif
return ret
endfunction
function! s:strwidthpart(str, width)
if a:width <= 0
return ''
endif
let ret = a:str
let width = s:wcswidth(a:str)
while width > a:width
let char = matchstr(ret, '.$')
let ret = ret[: -1 - len(char)]
let width -= s:wcswidth(char)
endwhile
return ret
endfunction
function! s:strwidthpart_reverse(str, width)
if a:width <= 0
return ''
endif
let ret = a:str
let width = s:wcswidth(a:str)
while width > a:width
let char = matchstr(ret, '^.')
let ret = ret[len(char) :]
let width -= s:wcswidth(char)
endwhile
return ret
endfunction
if v:version >= 703
" Use builtin function.
function! s:wcswidth(str)
return strwidth(a:str)
endfunction
else
function! s:wcswidth(str)
if a:str =~# '^[\x00-\x7f]*$'
return strlen(a:str)
end
let mx_first = '^\(.\)'
let str = a:str
let width = 0
while 1
let ucs = char2nr(substitute(str, mx_first, '\1', ''))
if ucs == 0
break
endif
let width += s:_wcwidth(ucs)
let str = substitute(str, mx_first, '', '')
endwhile
return width
endfunction
" UTF-8 only.
function! s:_wcwidth(ucs)
let ucs = a:ucs
if (ucs >= 0x1100
\ && (ucs <= 0x115f
\ || ucs == 0x2329
\ || ucs == 0x232a
\ || (ucs >= 0x2e80 && ucs <= 0xa4cf
\ && ucs != 0x303f)
\ || (ucs >= 0xac00 && ucs <= 0xd7a3)
\ || (ucs >= 0xf900 && ucs <= 0xfaff)
\ || (ucs >= 0xfe30 && ucs <= 0xfe6f)
\ || (ucs >= 0xff00 && ucs <= 0xff60)
\ || (ucs >= 0xffe0 && ucs <= 0xffe6)
\ || (ucs >= 0x20000 && ucs <= 0x2fffd)
\ || (ucs >= 0x30000 && ucs <= 0x3fffd)
\ ))
return 2
endif
return 1
endfunction
endif
let s:is_windows = has('win16') || has('win32') || has('win64') || has('win95')
let s:is_cygwin = has('win32unix')
let s:is_mac = !s:is_windows && !s:is_cygwin
\ && (has('mac') || has('macunix') || has('gui_macvim') ||
\ (!isdirectory('/proc') && executable('sw_vers')))
let s:is_unix = has('unix')
function! s:is_windows()
return s:is_windows
endfunction
function! s:is_cygwin()
return s:is_cygwin
endfunction
function! s:is_mac()
return s:is_mac
endfunction
function! s:is_unix()
return s:is_unix
endfunction
function! s:_deprecated2(fname)
echomsg printf("Vital.Prelude.%s is deprecated!",
\ a:fname)
endfunction
function! s:smart_execute_command(action, word)
execute a:action . ' ' . (a:word == '' ? '' : '`=a:word`')
endfunction
function! s:escape_file_searching(buffer_name)
return escape(a:buffer_name, '*[]?{}, ')
endfunction
function! s:escape_pattern(str)
return escape(a:str, '~"\.^$[]*')
endfunction
function! s:getchar(...)
let c = call('getchar', a:000)
return type(c) == type(0) ? nr2char(c) : c
endfunction
function! s:getchar_safe(...)
let c = s:input_helper('getchar', a:000)
return type(c) == type("") ? c : nr2char(c)
endfunction
function! s:input_safe(...)
return s:input_helper('input', a:000)
endfunction
function! s:input_helper(funcname, args)
let success = 0
if inputsave() !=# success
throw 'inputsave() failed'
endif
try
return call(a:funcname, a:args)
finally
if inputrestore() !=# success
throw 'inputrestore() failed'
endif
endtry
endfunction
function! s:set_default(var, val)
if !exists(a:var) || type({a:var}) != type(a:val)
let {a:var} = a:val
endif
endfunction
function! s:set_dictionary_helper(variable, keys, pattern)
call s:_deprecated2('set_dictionary_helper')
for key in split(a:keys, '\s*,\s*')
if !has_key(a:variable, key)
let a:variable[key] = a:pattern
endif
endfor
endfunction
function! s:substitute_path_separator(path)
return s:is_windows ? substitute(a:path, '\\', '/', 'g') : a:path
endfunction
function! s:path2directory(path)
return s:substitute_path_separator(isdirectory(a:path) ? a:path : fnamemodify(a:path, ':p:h'))
endfunction
function! s:_path2project_directory_git(path)
let parent = a:path
while 1
let path = parent . '/.git'
if isdirectory(path) || filereadable(path)
return parent
endif
let next = fnamemodify(parent, ':h')
if next == parent
return ''
endif
let parent = next
endwhile
endfunction
function! s:_path2project_directory_svn(path)
let search_directory = a:path
let directory = ''
let find_directory = s:escape_file_searching(search_directory)
let d = finddir('.svn', find_directory . ';')
if d == ''
return ''
endif
let directory = fnamemodify(d, ':p:h:h')
" Search parent directories.
let parent_directory = s:path2directory(
\ fnamemodify(directory, ':h'))
if parent_directory != ''
let d = finddir('.svn', parent_directory . ';')
if d != ''
let directory = s:_path2project_directory_svn(parent_directory)
endif
endif
return directory
endfunction
function! s:_path2project_directory_others(vcs, path)
let vcs = a:vcs
let search_directory = a:path
let find_directory = s:escape_file_searching(search_directory)
let d = finddir(vcs, find_directory . ';')
if d == ''
return ''
endif
return fnamemodify(d, ':p:h:h')
endfunction
function! s:path2project_directory(path, ...)
let is_allow_empty = get(a:000, 0, 0)
let search_directory = s:path2directory(a:path)
let directory = ''
" Search VCS directory.
for vcs in ['.git', '.bzr', '.hg', '.svn']
if vcs ==# '.git'
let directory = s:_path2project_directory_git(search_directory)
elseif vcs ==# '.svn'
let directory = s:_path2project_directory_svn(search_directory)
else
let directory = s:_path2project_directory_others(vcs, search_directory)
endif
if directory != ''
break
endif
endfor
" Search project file.
if directory == ''
for d in ['build.xml', 'prj.el', '.project', 'pom.xml', 'package.json',
\ 'Makefile', 'configure', 'Rakefile', 'NAnt.build',
\ 'P4CONFIG', 'tags', 'gtags']
let d = findfile(d, s:escape_file_searching(search_directory) . ';')
if d != ''
let directory = fnamemodify(d, ':p:h')
break
endif
endfor
endif
if directory == ''
" Search /src/ directory.
let base = s:substitute_path_separator(search_directory)
if base =~# '/src/'
let directory = base[: strridx(base, '/src/') + 3]
endif
endif
if directory == '' && !is_allow_empty
" Use original path.
let directory = search_directory
endif
return s:substitute_path_separator(directory)
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo
" vim:set et ts=2 sts=2 sw=2 tw=0:

View File

@@ -0,0 +1,8 @@
brightest
439e6d2
Coaster
Prelude
Coaster.Buffer
Coaster.Highlight
Coaster.Search

133
doc/brightest.jax Normal file
View File

@@ -0,0 +1,133 @@
brightest.txt カーソル下の単語を常にハイライトするプラグイン
==============================================================================
概要 *brightest-introduction*
*brightest* はカーソル下の単語をカーソルが移動する度にハイライトするプラグインで
す。
==============================================================================
インターフェース *brightest-interface*
------------------------------------------------------------------------------
コマンド *brightest-commands*
:BrightestEnable *:BrightestEnable*
ハイライトを有効にします。
この状態が既定値になります。
:BrightestDisable *:BrightestDisable*
ハイライトを無効にします。
==============================================================================
設定 *brightest-setting*
------------------------------------------------------------------------------
変数 *brightest-variables*
g:brightest#enable_filetypes *g:brightest#enable_filetypes*
有効にする 'filetype' を設定します。
設定されていない 'filetype' は "_" の値を使用します。
デフォルトではすべての 'filetype' が有効です。
Example: >
" filetype=cpp を無効にする
let g:brightest#enable_filetypes = {
\ "cpp" : 0
\}
" filetype=vim のみを有効にする
let g:brightest#enable_filetypes = {
\ "_" : 0
\ "vim" : 1
\}
<
g:brightest_pattern *g:brightest_pattern*
ハイライトするカーソル位置の単語のパターンを設定します。
任意の範囲をハイライトしたい場合はこの変数を変更してください。
また、空の文字列が設定されている場合は |<cword>|
の値がハイライトする単語として使用されます。
Default: >
let brightest_pattern = ""
<
Example: >
" 英数字 + _ の範囲をハイライトする単語として扱う
let brightest_pattern = '\w\+'
<
b:brightest_pattern *b:brightest_pattern*
|g:brightest_pattern| のバッファローカル版です。
|g:brightest_pattern| よりも優先して使用されます。
g:brightest_highlight *g:brightest_highlight*
カーソル下の単語をハイライトする |brightest-highlight| の設定です。
この設定でバッファ内にあるカーソル下の単語をハイライトします。
Default: >
let g:brightest_highlight = {
\ "group" : "WarningMsg",
\ "priority" : -1,
\ "format" : '\<%s\>',
\ }
<
Example: >
" 単語をアンダーラインでハイライトして、
" matchadd() の優先順位を 1000 にする
let g:brightest_highlight = {
\ "group" : "BrightestUnderline",
\ "priority" : 1000
\ }
<
b:brightest_highlight *b:brightest_highlight*
|g:brightest_highlight| のバッファローカル版です。
|g:brightest_highlight| よりも優先して使用されます。
g:brightest_highlight_in_corsur *g:brightest_highlight_in_cursor*
|g:brightest_highlight| と同等の設定ですが、カーソル行の単語のみに反映
されるハイライトの設定です。
'cursorline' と併用して使用する場合はこの設定を使用してください。
b:brightest_highlight_in_corsur *b:brightest_highlight_in_corsur*
|g:brightest_highlight_in_corsur| のバッファローカル版です。
|g:brightest_highlight_in_corsur| よりも優先して使用されます。
==============================================================================
ハイライトグループ *brightest-highlight_group*
BrightestUnderline *BrightestUnderline*
アンダーラインでハイライトします。
==============================================================================
ハイライト *brightest-highlight*
ハイライトの設定を行う辞書です。
ハイライトの設定には以下のキーの値が設定できます。
- "group" *brightest-highlight-group*
ハイライトグループを設定します。
空の文字列が設定されているとハイライトはされません。
- "priority" *brightest-highlight-priority*
matchadd()| の {priority} に設定される数値です。
- "format" *brightest-highlight-format*
単語をハイライトする際のフォーマットを設定します。
Example: >
" 単語をアンダーラインでハイライトして、
" matchadd() の優先順位を 1000 にする
let g:brightest_highlight = {
\ "group" : "BrightestUnderline",
\ "priority" : 1000
\ }
<
==============================================================================
vim:tw=78:fo=tcq2mM:ts=8:ft=help:norl

68
plugin/brightest.vim Normal file
View File

@@ -0,0 +1,68 @@
scriptencoding utf-8
if exists('g:loaded_brightest')
finish
endif
let g:loaded_brightest = 1
let s:save_cpo = &cpo
set cpo&vim
let g:brightest_pattern = get(g:, "brightest_pattern", '')
" let g:brightest_pattern = get(g:, "brightest_pattern", '\k\+')
" let g:brightest_highlight_group = get(g:, "brightest_highlight_group", "WarningMsg")
" let g:brightest_highlight_group_in_cursor = get(g:, "brightest_highlight_group_in_cursor", "")
" let g:brightest_highlight_group_in_cursorline = get(g:, "brightest_highlight_group_in_cursorline", "")
let g:brightest_enable = get(g:, "brightest_enable", 1)
let s:highlight_default = {
\ "group" : "WarningMsg",
\ "priority" : -1,
\ "format" : '\<%s\>',
\}
let g:brightest_highlight = get(g:, "brightest_highlight", {})
function! s:highlight()
return get(b:, "brightest_highlight", extend(s:highlight_default, g:brightest_highlight))
endfunction
let s:highlight_in_cursorline_default = {
\ "group" : "",
\ "priority" : -1,
\ "format" : '\<%s\>',
\}
let g:brightest_highlight_in_cursorline = get(g:, "brightest_highlight_in_cursorline", {})
function! s:highlight_in_cursorline()
return get(b:, "brightest_highlight_in_cursorline", extend(s:highlight_in_cursorline_default, g:brightest_highlight_in_cursorline))
endfunction
function! s:init_hl()
highlight BrightestDefaultCursorWord gui=underline guifg=NONE
highlight BrightestUnderline term=underline cterm=underline gui=underline
endfunction
function! s:hl()
call brightest#highlight(
\ get(b:, "brightest_pattern", g:brightest_pattern),
\ s:highlight(),
\ s:highlight_in_cursorline(),
\ )
endfunction
command! -bar BrightestEnable let g:brightest_enable = 1 | call s:hl()
command! -bar BrightestDisable let g:brightest_enable = 0 | call brightest#hl_clear()
augroup brightest
autocmd!
autocmd CursorMoved * call s:hl()
autocmd BufLeave,WinLeave,InsertEnter * call brightest#hl_clear()
autocmd ColorScheme * call s:init_hl()
augroup END
let &cpo = s:save_cpo
unlet s:save_cpo