From a736693f07666b4ced40deb1ec4e91032d85581e Mon Sep 17 00:00:00 2001 From: Maxim Likhachev Date: Wed, 23 Mar 2022 16:20:17 +0300 Subject: [PATCH] vim: ++haskell, pointfree, coc --- etc/soft/nvim/+plugins/vim-pointfree/Makefile | 8 ++ etc/soft/nvim/+plugins/vim-pointfree/README.md | 24 ++++ .../+plugins/vim-pointfree/autoload/pointfree.vim | 45 ++++++ .../vim-pointfree/autoload/pointfree/line.vim | 19 +++ .../vim-pointfree/autoload/pointfree/visual.vim | 48 +++++++ .../vim-pointfree/autoload/pointfree/window.vim | 27 ++++ .../nvim/+plugins/vim-pointfree/tools/init.vim | 3 + etc/soft/nvim/coc-settings.json | 153 ++++++++++++--------- 8 files changed, 262 insertions(+), 65 deletions(-) create mode 100644 etc/soft/nvim/+plugins/vim-pointfree/Makefile create mode 100644 etc/soft/nvim/+plugins/vim-pointfree/README.md create mode 100644 etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree.vim create mode 100644 etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/line.vim create mode 100644 etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/visual.vim create mode 100644 etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/window.vim create mode 100644 etc/soft/nvim/+plugins/vim-pointfree/tools/init.vim diff --git a/etc/soft/nvim/+plugins/vim-pointfree/Makefile b/etc/soft/nvim/+plugins/vim-pointfree/Makefile new file mode 100644 index 0000000..8f0a08a --- /dev/null +++ b/etc/soft/nvim/+plugins/vim-pointfree/Makefile @@ -0,0 +1,8 @@ +POINTFREE := $(shell pwd) +TOOLS := $(POINTFREE)/tools + +vim: + @vim -u $(TOOLS)/init.vim --cmd "set rtp=$(POINTFREE)" + +nvim: + @nvim -u $(TOOLS)/init.vim --cmd "set rtp=$(POINTFREE)" diff --git a/etc/soft/nvim/+plugins/vim-pointfree/README.md b/etc/soft/nvim/+plugins/vim-pointfree/README.md new file mode 100644 index 0000000..6288c61 --- /dev/null +++ b/etc/soft/nvim/+plugins/vim-pointfree/README.md @@ -0,0 +1,24 @@ +use vim to pointfree your haskell functions + +--- + +### Installation + +vim-pointfree depends on +[pointfree](https://hackage.haskell.org/package/pointfree), so make sure that +it is installed and available in your $PATH. + +To install using vim-plug: + +```viml +Plug 'm00qek/vim-pointfree' +``` + +### Configuration + +add something like the following on your vimrc + +```viml +nnoremap . :call pointfree#suggestions() +vnoremap . :call pointfree#selection() +``` diff --git a/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree.vim b/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree.vim new file mode 100644 index 0000000..20602ea --- /dev/null +++ b/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree.vim @@ -0,0 +1,45 @@ +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 pointfree#window#open(l:current_window, + \ l:suggestions, + \ a:Writer(l:current_window, a:coordinates)) + else + echoerr l:suggestions + endif +endfunction + +function! pointfree#optmized(expression) + let [l:success, l:suggestions] = s:pointfree(a:expression) + + if l:success + return l:suggestions[-1] + else + echoerr l:suggestions + endif +endfunction + +function! pointfree#selection() + call s:pointfree_window(function('pointfree#visual#expression'), + \ function('pointfree#visual#apply_command'), + \ pointfree#visual#coordinates()) +endfunction + +function! pointfree#suggestions() + call s:pointfree_window(function('pointfree#line#expression'), + \ function('pointfree#line#apply_command'), + \ pointfree#line#coordinates()) +endfunction diff --git a/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/line.vim b/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/line.vim new file mode 100644 index 0000000..519aa2b --- /dev/null +++ b/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/line.vim @@ -0,0 +1,19 @@ +function! pointfree#line#coordinates() + return { 'line': line('.') } +endfunction + +function! pointfree#line#apply(pointfree_window, coordinates) + let l:current_line = getline(a:firstline, a:lastline) + + call pointfree#window#close(a:pointfree_window) + + call setline(a:coordinates.line, l:current_line) +endfunction + +function! pointfree#line#apply_command(window, coordinates) + return "pointfree#line#apply(" . a:window . ", " . string(a:coordinates). ")" +endfunction + +function! pointfree#line#expression(coordinates) + return join(getline(a:firstline, a:lastline), "\n") +endfunction diff --git a/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/visual.vim b/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/visual.vim new file mode 100644 index 0000000..417b5f5 --- /dev/null +++ b/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/visual.vim @@ -0,0 +1,48 @@ +function! pointfree#visual#coordinates() + 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! pointfree#visual#apply(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 pointfree#window#close(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! pointfree#visual#apply_command(window, coordinates) + return "pointfree#visual#apply(" . a:window . ", " . string(a:coordinates). ")" +endfunction + +function! pointfree#visual#expression(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 diff --git a/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/window.vim b/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/window.vim new file mode 100644 index 0000000..ed6797f --- /dev/null +++ b/etc/soft/nvim/+plugins/vim-pointfree/autoload/pointfree/window.vim @@ -0,0 +1,27 @@ +function! s:close_if_pointfree(winnr) + if &l:filetype == 'haskell.pointfree' + silent bdelete! + endif +endfunction + +function! s:nmap(key, func) + execute 'nnoremap ' . a:key . ' :call ' . a:func . '' +endfunction + +function! pointfree#window#close(window) + silent windo call s:close_if_pointfree(winnr()) + call win_gotoid(a:window) +endfunction + +function! pointfree#window#open(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('' , a:writer) + call s:nmap('', 'pointfree#window#close(' . a:current_window . ")") +endfunction diff --git a/etc/soft/nvim/+plugins/vim-pointfree/tools/init.vim b/etc/soft/nvim/+plugins/vim-pointfree/tools/init.vim new file mode 100644 index 0000000..882fd42 --- /dev/null +++ b/etc/soft/nvim/+plugins/vim-pointfree/tools/init.vim @@ -0,0 +1,3 @@ +let mapleader = "\" + +nnoremap . :call pointfree#suggestions() diff --git a/etc/soft/nvim/coc-settings.json b/etc/soft/nvim/coc-settings.json index d348320..a19f5f8 100644 --- a/etc/soft/nvim/coc-settings.json +++ b/etc/soft/nvim/coc-settings.json @@ -1,67 +1,90 @@ { - "coc.preferences.formatOnSaveFiletypes": [], - "codeLens.enable": true, - "diagnostic.errorSign": "✖", - "suggest.autoTrigger": "none", - "languageserver": { - "golang": { - "command": "gopls", - "rootPatterns": ["go.mod", ".vim/", ".git/"], - "filetypes": ["go"], - "initializationOptions": { - "usePlaceholders": true - } - }, - "bash": { - "command": "bash-language-server", - "args": ["start"], - "filetypes": ["sh"], - "ignoredRootPaths": ["~"] - }, - "haskell": { - "command": "haskell-language-server-wrapper", - "args": ["--lsp", "--debug"], - "rootPatterns": ["*.cabal", "stack.yaml", "cabal.project", "package.yaml", "hie.yaml"], - "filetypes": ["haskell", "lhaskell"], - "settings": { - "languageServerHaskell": { - "hlintOn": true, - "maxNumberOfProblems": 10, - "completionSnippetsOn": true, - "formattingProvider": "none" - } - } - }, - "nix": { - "command": "rnix-lsp", - "filetypes": ["nix"] - }, - "python": { - "command": "pylsp", - "filetypes": ["python"], - "ignoredRootPaths": ["~"] - }, - "racket": { - "command": "racket", - "args": [ - "--lib", - "racket-langserver" - ], - "filetypes": [ - "scheme", - "racket" - ] - }, - "terraform": { - "command": "terraform-ls", - "args": ["serve"], - //"command": "terraform-lsp", - "filetypes": [ - "terraform", - "tf" - ], - "initializationOptions": {}, - "settings": {} - } - } + "coc.preferences.formatOnSaveFiletypes": ["haskell", "lhaskell", "hs", "lhs", "terraform", "hcl"], + "coc.preferences.enableMarkdown": true, + "coc.preferences.jumpCommand": "tab drop", + "outline.expandLevel": 3, + "outline.showLineNumber": true, + "outline.keepWindow": false, + "codeLens.position": "eol", + "codeLens.enable": true, + "diagnostic.errorSign": "✖", + "diagnostic.virtualText": false, + "diagnostic.virtualTextCurrentLineOnly": false, + "diagnostic.virtualTextLines": 1, + "suggest.autoTrigger": "none", + "suggest.disableKind": true, + "languageserver": { + "golang": { + "command": "gopls", + "rootPatterns": ["go.mod", ".vim/", ".git/"], + "filetypes": ["go"], + "initializationOptions": { + "usePlaceholders": true + } + }, + "bash": { + "command": "bash-language-server", + "args": ["start"], + "filetypes": ["sh"], + "ignoredRootPaths": ["~"] + }, + "haskell": { + "command": "haskell-language-server-wrapper", + "args": ["--lsp", "--debug"], + "rootPatterns": [ + "*.cabal", + "cabal.config", + "cabal.project", + "hie.yaml", + "package.yaml", + "stack.yaml" + ], + "filetypes": [ + "hs", + "lhs", + "haskell", + "lhaskell" + ], + "settings": { + "languageServerHaskell": { + "hlintOn": true, + "maxNumberOfProblems": 20, + "completionSnippetsOn": true, + "formattingProvider": "stylish-haskell" + }, + "initializationOptions": {} + } + }, + "nix": { + "command": "rnix-lsp", + "filetypes": ["nix"] + }, + "python": { + "command": "pylsp", + "filetypes": ["python"], + "ignoredRootPaths": ["~"] + }, + "racket": { + "command": "racket", + "args": [ + "--lib", + "racket-langserver" + ], + "filetypes": [ + "scheme", + "racket" + ] + }, + "terraform": { + "command": "terraform-ls", + "args": ["serve"], + //"command": "terraform-lsp", + "filetypes": [ + "terraform", + "tf" + ], + "initializationOptions": {}, + "settings": {} + } + } }