Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comment aware eval top #333

Merged
merged 5 commits into from
Apr 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be helpful there is an examples like the following.
https:/liquidz/vim-iced/blob/3.1.3/doc/vim-iced.txt#L400

Also if you don't mind, could you update the following document page?
https:/liquidz/vim-iced/blob/3.1.3/doc/pages/configuration/evaluation.adoc#evaluation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, I've put the example in the adoc and linked to it from vim doc

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