You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
8.6 KiB
298 lines
8.6 KiB
set makeprg=ghc\ %\ -o\ %< " Компилятор |
|
|
|
set expandtab |
|
set tabstop=8 |
|
set shiftwidth=8 |
|
|
|
set formatprg=stylish-haskell |
|
|
|
runtime syntax/custom/HaskellConceal.vim |
|
|
|
" ============================================================================= |
|
" Descriptions: Provide a function providing folding information for haskell |
|
" files. |
|
" Maintainer: Vincent B (twinside@gmail.com) |
|
" Warning: Assume the presence of type signatures on top of your functions to |
|
" work well. |
|
" Usage: drop in ~/vimfiles/plugin or ~/.vim/plugin |
|
" Version: 1.2 |
|
" Changelog: - 1.2 : Reacting to file type instead of file extension. |
|
" - 1.1 : Adding foldtext to bet more information. |
|
" - 1.0 : initial version |
|
" ============================================================================= |
|
" Top level bigdefs |
|
fun! s:HaskellFoldMaster( line ) "{{{ |
|
return a:line =~# '^data\s' |
|
\ || a:line =~# '^type\s' |
|
\ || a:line =~# '^newtype\s' |
|
\ || a:line =~# '^class\s' |
|
\ || a:line =~# '^instance\s' |
|
\ || a:line =~ '^[^:]\+\s*::' |
|
endfunction "}}} |
|
|
|
" Top Level one line shooters. |
|
fun! s:HaskellSnipGlobal(line) "{{{ |
|
return a:line =~# '^module' |
|
\ || a:line =~# '^import' |
|
\ || a:line =~# '^infix[lr]\s' |
|
endfunction "}}} |
|
|
|
" The real folding function |
|
fun! HaskellFold( lineNum ) "{{{ |
|
let line = getline( a:lineNum ) |
|
|
|
" Beginning of comment |
|
if line =~ '^\s*--' || line =~ '^\s*{-' |
|
return 2 |
|
endif |
|
|
|
if line =~ '^import' |
|
return 2 |
|
endif |
|
|
|
if s:HaskellSnipGlobal( line ) |
|
return 0 |
|
endif |
|
|
|
if line =~ '^\s*$' |
|
let nextline = getline(a:lineNum + 1) |
|
if s:HaskellFoldMaster( nextline ) > 0 || s:HaskellSnipGlobal( nextline ) > 0 |
|
\ || nextline =~ "^--" || nextline =~ "^{-" |
|
return 0 |
|
else |
|
return -1 |
|
endif |
|
endif |
|
|
|
return 1 |
|
endfunction "}}} |
|
|
|
" This function skim over function definitions |
|
" skiping comments line : |
|
" -- .... |
|
" and merging lines without first non space element, to |
|
" catch the full type expression. |
|
fun! HaskellFoldText() "{{{ |
|
let i = v:foldstart |
|
let retVal = '' |
|
let began = 0 |
|
|
|
let commentOnlyLine = '^\s*--.*$' |
|
let monoLineComment = '\s*--.*$' |
|
let nonEmptyLine = '^\s\+\S' |
|
let emptyLine = '^\s*$' |
|
let multilineCommentBegin = '^\s*{-' |
|
let multilineCommentEnd = '-}' |
|
|
|
let short = get(g:, 'haskellFold_ShortText', 0) |
|
let isMultiLine = 0 |
|
|
|
let line = getline(i) |
|
while i <= v:foldend |
|
|
|
if isMultiLine |
|
if line =~ multilineCommentEnd |
|
let isMultiLine = 0 |
|
let line = substitute(line, '.*-}', '', '') |
|
|
|
if line =~ emptyLine |
|
let i = i + 1 |
|
let line = getline(i) |
|
end |
|
else |
|
let i = i + 1 |
|
let line = getline(i) |
|
end |
|
else |
|
if line =~ multilineCommentBegin |
|
let isMultiLine = 1 |
|
continue |
|
elseif began == 0 && !(line =~ commentOnlyLine) |
|
let retVal = substitute(line, monoLineComment, ' ','') |
|
let began = 1 |
|
elseif began != 0 && line =~ nonEmptyLine && !short |
|
let tempVal = substitute( line, '\s\+\(.*\)$', ' \1', '' ) |
|
let retVal = retVal . substitute(tempVal, '\s\+--.*', ' ','') |
|
elseif began != 0 |
|
break |
|
endif |
|
|
|
let i = i + 1 |
|
let line = getline(i) |
|
endif |
|
endwhile |
|
|
|
if retVal == '' |
|
" We didn't found any meaningfull text |
|
return foldtext() |
|
endif |
|
|
|
return retVal |
|
endfunction "}}} |
|
|
|
setlocal foldexpr=HaskellFold(v:lnum) |
|
setlocal foldtext=HaskellFoldText() |
|
setlocal foldmethod=expr |
|
|
|
" ============================================================================= |
|
" vim-pointfree depends on |
|
" [pointfree](https://hackage.haskell.org/package/pointfree), so make sure that |
|
" it is installed and available in your $PATH. |
|
" |
|
" 'm00qek/vim-pointfree' |
|
" ============================================================================= |
|
|
|
if exists('g:haskell_pointfree') |
|
finish |
|
endif |
|
|
|
let g:haskell_pointfree = 1 |
|
|
|
function! HaskellPointfreeLineCoordinates() |
|
return { 'line': line('.') } |
|
endfunction |
|
|
|
function! HaskellPointfreeLineApply(pointfree_window, coordinates) |
|
let l:current_line = getline(a:firstline, a:lastline) |
|
|
|
call HaskellPointfreeWindowClose(a:pointfree_window) |
|
|
|
call setline(a:coordinates.line, l:current_line) |
|
endfunction |
|
|
|
function! HaskellPointfreeLineApply_command(window, coordinates) |
|
return "HaskellPointfreeLineApply(" . a:window . ", " . string(a:coordinates). ")" |
|
endfunction |
|
|
|
function! HaskellPointfreeLineExpression(coordinates) |
|
return join(getline(a:firstline, a:lastline), "\n") |
|
endfunction |
|
|
|
function! HaskellPointfreeVisualCoordinates() |
|
let [start_line, start_column] = getpos("'<")[1:2] |
|
let [end_line, end_column] = getpos("'>")[1:2] |
|
|
|
return { 'start_line': start_line, |
|
\ 'start_column': start_column, |
|
\ 'end_line': end_line, |
|
\ 'end_column': end_column |
|
\ } |
|
endfunction |
|
|
|
function! HaskellPointfreeVisualApply(pointfree_window, coordinates) |
|
let l:current_line = getline(a:firstline, a:lastline)[0] |
|
let l:hreg = getreg("h") |
|
call setreg("h", trim(l:current_line)) |
|
|
|
call HaskellPointfreeWindowClose(a:pointfree_window) |
|
|
|
call setpos("'<", [ a:pointfree_window |
|
\ , a:coordinates.start_line |
|
\ , a:coordinates.start_column ]) |
|
|
|
call setpos("'>", [ a:pointfree_window |
|
\ , a:coordinates.end_line |
|
\ , a:coordinates.end_column ]) |
|
|
|
normal! gv"hp |
|
call setreg("h", l:hreg) |
|
endfunction |
|
|
|
function! HaskellPointfreeVisualApply_command(window, coordinates) |
|
return "HaskellPointfreeVisualApply(" . a:window . ", " . string(a:coordinates). ")" |
|
endfunction |
|
|
|
function! HaskellPointfreeVisualExpression(coordinates) |
|
let lines = getline(a:coordinates.start_line, a:coordinates.end_line) |
|
if len(lines) == 0 |
|
return '' |
|
endif |
|
|
|
let l:start = a:coordinates.start_column - 1 |
|
let l:end = a:coordinates.end_column - (&selection == 'inclusive' ? 1 : 2) |
|
|
|
let lines[0] = lines[0][l:start :] |
|
let lines[-1] = lines[-1][: l:end] |
|
|
|
return join(lines, "\n") |
|
endfunction |
|
|
|
function! s:close_if_pointfree(winnr) |
|
if &l:filetype == 'haskell.pointfree' |
|
silent bdelete! |
|
endif |
|
endfunction |
|
|
|
function! s:nmap(key, func) |
|
execute 'nnoremap <silent> <buffer> ' . a:key . ' :call ' . a:func . '<CR>' |
|
endfunction |
|
|
|
function! HaskellPointfreeWindowClose(window) |
|
silent windo call s:close_if_pointfree(winnr()) |
|
call win_gotoid(a:window) |
|
endfunction |
|
|
|
function! HaskellPointfreeWindowOpen(current_window, suggestions, writer) |
|
execute 'silent botright 10new' |
|
call setline(1, a:suggestions) |
|
|
|
setlocal readonly nomodifiable |
|
setlocal nonumber |
|
let &l:filetype = 'haskell.pointfree' |
|
setlocal syntax=haskell |
|
|
|
call s:nmap('<CR>' , a:writer) |
|
call s:nmap('<Esc>', 'HaskellPointfreeWindowClose(' . a:current_window . ")") |
|
endfunction |
|
|
|
function! s:pointfree(expression) |
|
let l:suggestions = system('pointfree --verbose '.shellescape(a:expression)) |
|
let l:suggestions = split(l:suggestions, "\n")[3:] |
|
|
|
if v:shell_error == 0 |
|
return [v:true, insert(l:suggestions, a:expression)] |
|
endif |
|
|
|
return [v:false, "Sorry, I couldn't pointfree your expression :("] |
|
endfunction |
|
|
|
function! s:pointfree_window(Expression, Writer, coordinates) |
|
let l:current_window = win_getid() |
|
let [l:success, l:suggestions] = s:pointfree(a:Expression(a:coordinates)) |
|
|
|
if l:success |
|
call HaskellPointfreeWindowOpen(l:current_window, |
|
\ l:suggestions, |
|
\ a:Writer(l:current_window, a:coordinates)) |
|
else |
|
echoerr l:suggestions |
|
endif |
|
endfunction |
|
|
|
function! HaskellPointfreeOptmized(expression) |
|
let [l:success, l:suggestions] = s:pointfree(a:expression) |
|
|
|
if l:success |
|
return l:suggestions[-1] |
|
else |
|
echoerr l:suggestions |
|
endif |
|
endfunction |
|
|
|
function! HaskellPointfreeSelection() |
|
call s:pointfree_window(function('HaskellPointfreeVisualExpression'), |
|
\ function('HaskellPointfreeVisualApply_command'), |
|
\ HaskellPointfreeVisualCoordinates()) |
|
endfunction |
|
|
|
function! HaskellPointfreeSuggestions() |
|
call s:pointfree_window(function('HaskellPointfreeLineExpression'), |
|
\ function('HaskellPointfreeLineApply_command'), |
|
\ HaskellPointfreeLineCoordinates()) |
|
endfunction |
|
|
|
nnoremap <silent> <Leader>. :call HaskellPointfreeSuggestions()<CR> |
|
vnoremap <silent> <Leader>. :call HaskellPointfreeSelection()<CR> |
|
|
|
" ============================================================================= |
|
|
|
|