Skip to content

Commit

Permalink
Merge pull request #333 from pinealan/comment-aware-eval-top
Browse files Browse the repository at this point in the history
Comment aware eval top
  • Loading branch information
liquidz authored Apr 25, 2021
2 parents 0a96584 + 526121b commit 04892cf
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. This change

== Unreleased (dev)

* IcedEvalOuterTopList selects topmost form that is not a comment

== 3.1.3 (2021-04-24)
// {{{
=== Changed
Expand Down
2 changes: 1 addition & 1 deletion autoload/iced/nrepl/eval.vim
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ endfunction

function! iced#nrepl#eval#outer_top_list(...) abort
if ! iced#nrepl#check_session_validity() | return | endif
let ret = iced#paredit#get_current_top_object('(', ')')
let ret = iced#paredit#get_top_list_in_comment()
let code = get(ret, 'code')
if empty(code)
return iced#message#error('finding_code_error')
Expand Down
69 changes: 69 additions & 0 deletions autoload/iced/paredit.vim
Original file line number Diff line number Diff line change
Expand Up @@ -223,5 +223,74 @@ function! iced#paredit#get_outer_list() abort
return code
endfunction

" from vim-sexp
function! s:get_visual_marks() abort
return [getpos("'<"), getpos("'>")]
endfunction

function! s:set_visual_marks(marks) abort
call setpos("'<", a:marks[0])
call setpos("'>", a:marks[1])
endfunction

" Return visually selected text without changing selection state and registers
function! s:get_visual_selection() abort
let reg_save = @@
silent normal! y
let result = @@
let @@ = reg_save
silent normal! gv
return result
endfunction

function! s:get_visual_selection_and_pos() abort
let reg_save = @@
silent normal! y
let code = @@
let pos = getcurpos()
let @@ = reg_save
silent normal! gv
return {'code': code, 'curpos': pos}
endfunction

function! s:select_top_list(top_code) abort
let reg_save = @@
try
while (v:true)
call sexp#select_current_list('v', 0, 1)
let current_marks = s:get_visual_marks()

call sexp#docount(2, 'sexp#select_current_list', 'v', 0, 1)
let next_code = s:get_visual_selection()

if (next_code ==# a:top_code) | break | endif
endwhile
call s:set_visual_marks(current_marks)
normal! gv
finally
let @@ = reg_save
endtry
endfunction

function! iced#paredit#get_top_list_in_comment() abort
let view = winsaveview()
let curpos = getpos('.')

" First use vim-sexp optimized top form selector
call sexp#select_current_top_list('v', 0)
let top_code = s:get_visual_selection()

if (stridx(top_code, '(comment') == 0)
" Select up one by one if the top list is a (comment ...) form
execute "normal! \<Esc>"
call setpos('.', curpos)
call s:select_top_list(top_code)
endif
let ret = s:get_visual_selection_and_pos()
execute "normal! \<Esc>"
call winrestview(view)
return ret
endfunction

let &cpo = s:save_cpo
unlet s:save_cpo
2 changes: 1 addition & 1 deletion autoload/iced/socket_repl.vim
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ function! iced#socket_repl#eval(code, ...) abort
endfunction

function! iced#socket_repl#eval_outer_top_list(...) abort " {{{
let ret = iced#paredit#get_current_top_object('(', ')')
let ret = iced#paredit#get_top_list_in_comment()
let code = get(ret, 'code')
if empty(code)
return iced#message#error('finding_code_error')
Expand Down
18 changes: 13 additions & 5 deletions doc/pages/configuration/evaluation.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@

==== Eval inside comment [[eval_inside_comment]]

`comment` form is useful for checking behavior.
`comment` form is useful during development for checking behavior.
You can use <<evaluate_outer_list>> range to evaluate codes inside `comment` form,
but it is bored that some cursor movements are required.
but it is cumbersome as some cursor movements are required.

{help_html}#%3AIcedEvalOuterTopList[IcedEvalOuterTopList] helps by selecting different code to be evaluated when the current top form is a `comment`.
If the cursor is in a form nested inside the comment, the code to be evaluated will be the cursor's topmost form in the comment, rather than the comment form itself.

{help_html}#g%3Aiced%23eval%23inside_comment[g:iced#eval#inside_comment] is a configuration that allow you to evaluate inside `comment` form with <<evaluate_outer_top_list>> range, and it is enabled by default.
When the cursor is otherwise at the same depth as the `comment` form itself, the `comment` will be evaluated as a `do` form.
This can be configured by {help_html}#g%3Aiced%23eval%23inside_comment[g:iced#eval#inside_comment], and it is enabled by default.

.Example (📍 means cursor position)
[source,clojure]
----
(comment📍 ;; Execute `:IcedEvalOuterTopList`
(+ 1 2 3)) ;; => 6
(comment
(print (📍"Hello")) ;; Execute `:IcedEvalOuterTopList`
(print ("world"))) ;; => hello
(comment
📍(print ("hello")) ;; Execute `:IcedEvalOuterTopList`
(print ("world"))) ;; => helloworld
----
20 changes: 10 additions & 10 deletions doc/vim-iced.txt
Original file line number Diff line number Diff line change
Expand Up @@ -230,28 +230,28 @@ REBEL READLINE~
(ns user
(:require [nrepl.server :as nrepl-server]
[clojure.java.io :as io]))
(def nrepl-port 7888)
(defonce nrepl-server (atom nil))
(defn cider-middleware
"Get cider middleware, see
"Get cider middleware, see
https:/clojure-emacs/cider-nrepl/issues/447"
[]
(require 'cider.nrepl)
(map ns-resolve
['cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl]
(map ns-resolve
['cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl 'cider.nrepl]
['wrap-classpath 'wrap-clojuredocs 'wrap-complete 'wrap-debug 'wrap-format 'wrap-info 'wrap-macroexpand 'wrap-ns 'wrap-out 'wrap-spec 'wrap-test 'wrap-trace 'wrap-undef 'wrap-xref]))
(defn dev-middleware []
(mapcat (fn [[ns syms]] (require ns) (map (partial ns-resolve ns) syms))
[['refactor-nrepl.middleware ['wrap-refactor]] ['iced.nrepl ['wrap-iced]]]))
(defn nrepl-handler
"Re-implement cider-nrepl-handler so we can add middleware to the default list"
[]
(apply nrepl-server/default-handler (concat (cider-middleware) (dev-middleware))))
(defn start-nrepl-server! []
(reset!
nrepl-server
Expand All @@ -267,7 +267,7 @@ REBEL READLINE~
(io/delete-file ".nrepl-port" true)
(System/exit 0)))
<
Start the Rebel Readline REPL and from it's prompt start the nREPL server
Start the Rebel Readline REPL and from it's prompt start the nREPL server
using `start-nrepl-server!`, then in Vim do `:IcedConnect`.

==============================================================================
Expand Down Expand Up @@ -819,8 +819,8 @@ COMMANDS *vim-iced-commands*

*:IcedEvalOuterTopList*
:IcedEvalOuterTopList
Work same as `<Plug>(iced_eval)<Plug>(sexp_outer_top_list)`,
without scrolling.
Evaluate topmost form that is not a comment where the cursor currently is.
See also https://liquidz.github.io/vim-iced/#configuration_evaluation
Key is mapped to |<Plug>(iced_eval_outer_top_list)|.

*:IcedEvalAtMark*
Expand Down Expand Up @@ -2213,7 +2213,7 @@ CONNECT PREPARED *hook_event_connect_prepared*
This hook only allows `function` hook type.
c.f. |hook_report_function|

Following list is passed to reporter.
Following list is passed to reporter.
e.g. `[{'label': 'nREPL', 'type': 'nrepl', 'port': 12345}]`

Reporter should return a list of dictionary which has same parameters.
Expand Down

0 comments on commit 04892cf

Please sign in to comment.