clojure-vim / clj-refactor.nvim Goto Github PK
View Code? Open in Web Editor NEWA neovim clojure refactoring plugin
A neovim clojure refactoring plugin
❯ nvim --version
NVIM v0.1.6-5-g46475a1
Build type: Dev
Compilation: /usr/bin/cc -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -Wconversion -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wvla -fstack-protector-strong -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -DHAVE_CONFIG_H -D_GNU_SOURCE -I/tmp/pkgbuild-0/neovim-git/src/neovim-git/build/config -I/tmp/pkgbuild-0/neovim-git/src/neovim-git/src -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/tmp/pkgbuild-0/neovim-git/src/neovim-git/build/src/nvim/auto -I/tmp/pkgbuild-0/neovim-git/src/neovim-git/build/include
Compiled by aurbuild@localhost
Optional features included (+) or not (-): +acl +iconv +jemalloc +tui
For differences from Vim, see :help vim-differences
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/share/nvim"
Edited slightly.
Tue Aug 23 2016 13:59:00 GMT+0100 (BST) clj-refactor.js: hello refactor
Tue Aug 23 2016 13:59:00 GMT+0100 (BST) clj-refactor.js: {:op "clean-ns", :path "/home/dominic/src/foo.clj", :prefix-rewriting "true", :prune-ns-form "true"} null [ { status: [ 'done' ],
id: 'fireplace-localhost-1471957137-9',
session: 'a29f48d8-b785-4804-add2-8a2788b11bef',
ns: '(ns foo\n (:require [clojure.core.async :as async]\n [foo.database :as db]))\n' } ]
Tue Aug 23 2016 13:59:00 GMT+0100 (BST) clj-refactor.js: clean-ns [ { status: [ 'done' ],
id: 'fireplace-localhost-1471957137-9',
session: 'a29f48d8-b785-4804-add2-8a2788b11bef',
ns: '(ns foo\n (:require [clojure.core.async :as async]\n [foo.database :as db]))\n' } ]
Tue Aug 23 2016 13:59:00 GMT+0100 (BST) clj-refactor.js: save RangeError: Offset is out of bounds
at RangeError (native)
at Buffer.write (buffer.js:761:21)
at encode (/home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:25:13)
at /home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:76:20
at Array.reduce (native)
at encode (/home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:75:17)
at /home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:76:20
at Array.reduce (native)
at encode (/home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:75:17)
at /home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:76:20 RangeError: Offset is out of bounds
at RangeError (native)
at Buffer.write (buffer.js:761:21)
at encode (/home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:25:13)
at /home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:76:20
at Array.reduce (native)
at encode (/home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:75:17)
at /home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:76:20
at Array.reduce (native)
at encode (/home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:75:17)
at /home/dominic/.files/nvim/plugged/node-host/node_modules/msgpack5rpc/node_modules/msgpack5/lib/encoder.js:76:20
Occurs when running crcn
, but also happens with other commands.
Any clues on where to start looking?
The add missing libspec example from clj-refactor.el dons't works.
https://github.com/clojure-emacs/clj-refactor.el/blob/master/examples/add-missing-libspec.gif
I have a test file with a bunch of test cases like:
(testing "frequency -> the nearest MIDI note"
(is (= (pitch/hz->midi 7.95) 0))
(is (= (pitch/hz->midi 8.176) 0))
(is (= (pitch/hz->midi 25.96) 20))
(is (= (pitch/hz->midi 26) 20))
(is (= (pitch/hz->midi 107.3) 45))
(is (= (pitch/hz->midi 261) 60))
(is (= (pitch/hz->midi 430) 69))
(is (= (pitch/hz->midi 439) 69))
(is (= (pitch/hz->midi 440) 69))
(is (= (pitch/hz->midi 441) 69))
(is (= (pitch/hz->midi 8372) 120)))
If I go into the example.pitch
namespace (aliased in the test file above as pitch
), move my cursor over the pitch/hz->midi
function name in the defn
form, and use crrs
to rename it to foop
, it renames the function in the example.pitch
namespace, but only replaces the first instance of pitch/hz->midi
in the test file with foop
:
(testing "frequency -> the nearest MIDI note"
(is (= (foop 7.95) 0))
(is (= (pitch/hz->midi 8.176) 0))
(is (= (pitch/hz->midi 25.96) 20))
(is (= (pitch/hz->midi 26) 20))
(is (= (pitch/hz->midi 107.3) 45))
(is (= (pitch/hz->midi 261) 60))
(is (= (pitch/hz->midi 430) 69))
(is (= (pitch/hz->midi 439) 69))
(is (= (pitch/hz->midi 440) 69))
(is (= (pitch/hz->midi 441) 69))
(is (= (pitch/hz->midi 8372) 120)))
Also note that it should have replaced it with pitch/foop
.
Tue Feb 09 2016 15:59:18 GMT+0000 (GMT) clj-refactor.js: hello refactor
Tue Feb 09 2016 15:59:18 GMT+0000 (GMT) clj-refactor.js: transforming #object[cljs.core.async.impl.channels.ManyToManyChannel]
Tue Feb 09 2016 15:59:19 GMT+0000 (GMT) clj-refactor.js: zip-it [Error: Invalid token: :, on line: 485, on column: 19] Error: Invalid token: :, on line: 485, on column: 19
at Error (native)
at Function.cljs.extended.reader.reader_error.cljs$core$IFn$_invoke$arity$variadic (/home/dominic/.config/nvim/plugged/clj-refactor.nvim/rplugin/node/clj-refactor.js:1840:141)
at cljs.extended.reader.reader_error (/home/dominic/.config/nvim/plugged/clj-refactor.nvim/rplugin/node/clj-refactor.js:1839:227)
at cljs.extended.reader.read_keyword (/home/dominic/.config/nvim/plugged/clj-refactor.nvim/rplugin/node/clj-refactor.js:1871:392)
at rewrite_clj.parser.keyword.parse_keyword (/home/dominic/.config/nvim/plugged/clj-refactor.nvim/rplugin/node/clj-refactor.js:2319:404)
at rewrite_clj.reader.read_with_meta (/home/dominic/.config/nvim/plugged/clj-refactor.nvim/rplugin/node/clj-refactor.js:1962:163)
at rewrite_clj.parser.core.parse_next (/home/dominic/.config/nvim/plugged/clj-refactor.nvim/rplugin/node/clj-refactor.js:2339:89)
at /home/dominic/.config/nvim/plugged/clj-refactor.nvim/rplugin/node/clj-refactor.js:2324:832
at /home/dominic/.config/nvim/plugged/clj-refactor.nvim/rplugin/node/clj-refactor.js:1963:437
at /home/dominic/.config/nvim/plugged/clj-refactor.nvim/rplugin/node/clj-refactor.js:902:199
Nothing works for me, first doesn't throw an error, subsequent calls display error:
E475: Invalid argument: Channel doesn't exist
If I have a bare-bones namespace declaration like:
(ns foo)
And I move my cursor over something like str/includes?
and type cram
, I get an error message: nil
If I add in a :require
part of the ns
form:
(ns foo
(:require []))
and then do the same thing, then it works.
I would guess that this is something to do with not being able to locate the :require
part of the ns
(because it doesn't exist yet) and not handling that case specially. I think the right behavior there would be to add the :require
form for you.
For example, I have this top-level form:
(defrpc campaigns
[& [opts]]
{:rpc/pre (and (have-api-key) (have-network))}
(->> (view/campaigns (network) opts)
(map #(safe-parse-json % :customfields))))
When I put my cursor on the (
before ->>
and enter cril
and enter cs
for the binding name, the result is:
(defrpc campaigns
[& [opts]]
{:rpc/pre (and (have-api-key) (have-network))}
(let [cs (->> (view/campaigns (network) opts))]
(map #(safe-parse-json % :customfields))))
cs
I use parinfer, so it re-balanced my parens because cs
was all the way to the left, so it was judged to be another top-level form. The bindings part of the let also got closed prematurely because the line after it wasn't indented far enough to the right.
If I disable parinfer and do the same thing, I get this, which is still not indented properly:
(defrpc campaigns
[& [opts]]
{:rpc/pre (and (have-api-key) (have-network))}
(let [cs (->> (view/campaigns (network) opts)
(map #(safe-parse-json % :customfields)))]
cs))
Note that not only is cs
not indented at all, the previous line also has incorrect indentation now because it didn't move from where it was before.
It could be implemented by using delegating a call to https://github.com/markwoodhall/vim-cljreloaded, if the vim-cljreloaded is installed.
A bug in clojurescript causes forward slashes /
anywhere in a file to get munged to \/
.
This actually breaks user code so I think in the short term we should extend IPrintWithWriter
and hack around the slash issue. I briefly looked into fixing the core issue but there are many more corner cases around translating javascript regex output back to a cljs regex.
A transform-test case:
(deftest testing-regex
(are [i j] (= i j)
"(re-find #\".*//foo.com/x\" foo)"
(pr-str
'(re-find #".*\/\/foo.com\/x" foo))))
Hi,
I think CCleanNS
has a bug. When applied to the following test file:
(ns clean-ns.reproduce-issue
(:refer-clojure :exclude [str keyword])
(:require [leihs.procurement.utils.core :refer [keyword str presence]])
(:require
[bidi.bidi :as bidi]))
(defn wrap-resolve-handler
([handler] (fn [request] (wrap-resolve-handler handler request)))
([handler request]
(let [path (or (-> request
:path-info
presence)
(-> request
:uri
presence))
{route-params :route-params, handler-key :handler}
(bidi/match-pair paths {:remainder path, :route paths})
handler-fn (handler-resolver handler-key)]
(handler (assoc request
:route-params route-params
:handler-key handler-key
:handler handler-fn)))))
The result is:
(ns clean-ns.reproduce-issue
(:refer-clojure :exclude [str keyword])
(:require [leihs.procurement.utils.core :refer [presence]]))
(defn wrap-resolve-handler
([handler] (fn [request] (wrap-resolve-handler handler request)))
([handler request]
(let [path (or (-> request
:path-info
presence)
(-> request
:uri
presence))
{route-params :route-params, handler-key :handler}
(bidi/match-pair paths {:remainder path, :route paths})
handler-fn (handler-resolver handler-key)]
(handler (assoc request
:route-params route-params
:handler-key handler-key
:handler handler-fn)))))
[bidi.bidi :as bidi]
was removed but is used in (bidi/match-pair paths {:remainder path, :route paths})
.
I have observed this behaviour in several files and in several required dependencies.
Thanks,
Matus
As mentioned here it would be really cool to have something to auto-convert from ->>
to eduction
Cljc should be easy by just modifying autocmd pattern: https://github.com/snoe/clj-refactor.nvim/blob/master/src/clj_refactor/main.cljs#L95
Cljs support might require some changes to connection logic.
I can't seem to get crrf
or crrd
to work at all. When I try, I get errors from Fireplace. One wrinkle is that I'm not exactly sure what I need to enter -- is it acceptable to just enter foo.clj
, or do I need to specify the entire path to the new filename?
I tried both of those, resulting in the error messages below. The first two are from crrf
, the latter two from crrd
.
Error: Error during fireplace#message: Can't find src dir prefix for path foo.clj
"src/workflow/pitch.clj" 31L, 1104C written
Error: Error during fireplace#message: Can't find src dir prefix for path src/workflow/foo.clj
"src/workflow/pitch.clj" 31L, 1104C written
Error: Error during fireplace#message: Can't find src dir prefix for path foo/pitch.clj
"src/workflow/pitch.clj" 31L, 1104C written
Error: Error during fireplace#message: Can't find src dir prefix for path src/foo/pitch.clj
1 change; before #200 1 seconds ago
Add a config for clean-ns in the following section:
My codebase doesn't use the same rules as cljfmt, so I have to go unformat the entire file after every refactor.
Configs for cljfmt (both in style and enabled/disabled) would be great.
Related, do we still need it as an automatic operation? Is there anywhere that the refactored form is any different?
I haven't been able to get anything working. Any ideas what I missed?
My init.vim has:
Plug 'neovim/node-host', { 'do': 'npm install -g neovim' }
Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
Plug 'clojure-vim/clj-refactor.nvim', { 'do': ':UpdateRemotePlugins'}
» nvim --version
NVIM v0.2.1-866-gf51a39701
Build type: Release
Compilation: /usr/local/Homebrew/Library/Homebrew/shims/super/clang -Wconversion -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_MSGPACK_HAS_FLOAT32 -DNDEBUG -DMIN_LOG_LEVEL=3 -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -I/tmp/neovim-20170910-3687-1oun6bl/build/config -I/tmp/neovim-20170910-3687-1oun6bl/src -I/usr/local/include -I/usr/local/include -I/usr/local/include -I/usr/local/include -I/usr/local/include -I/usr/local/include -I/usr/local/opt/gettext/include -I/usr/include -I/tmp/neovim-20170910-3687-1oun6bl/build/src/nvim/auto -I/tmp/neovim-20170910-3687-1oun6bl/build/include
Compiled by matthias.margush@C02NL39NG3QT
Features: +acl +iconv +jemalloc +tui
See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/local/Cellar/neovim/HEAD-f51a397_1/share/nvim"
» node --version
v8.4.0
» cat ~/.lein/profiles.clj
{:user {:plugins [[cider/cider-nrepl "0.15.0"]
[refactor-nrepl "2.3.1"]]}
:cloverage {:plugins [[lein-cloverage "1.0.9"]]
:dependencies [[com.fasterxml.jackson.core/jackson-core "2.7.9"]]}
:pretty {:plugins [[venantius/ultra "0.5.1"]]}}
» npm install -g neovim
/usr/local/bin/neovim-node-host -> /usr/local/lib/node_modules/neovim/bin/cli.js
+ [email protected]
updated 1 package in 1.552s
rplugin.vim contains:
" node plugins
call remote#host#RegisterPlugin('node', '/Users/matthias.margush/.local/share/nvim/plugged/clj-refactor.nvim/rplugin/node/clj-refactor.js', [
\ ])
Hi everyone
I don't know what I am doing wrong, but for every command I get an error in vim of type:
E492: Not an editor command: ...
How and what I have installed:
[refactor-nrepl "2.3.1"]
in my ~/.lein/profiles.clj
fileInside vim I have also done the following things:
:PlugInstall
:UpdateRemotePlugins
Both with expected success result.
I haven't done anything in regard to node-host as it is apparently a part of neovim itself now.
Any help is appreciated.
Matus
Given a form like this:
(deftest example-tests
(testing "something"
(is (= 1 1))
(-> foo bar baz)
(is (= 2 2))))
If I put my cursor on the (
to the left of the ->
and do cruw
(thread-unwind), I get this, which is good:
(deftest example-tests
(testing "something"
(is (= 1 1))
(-> (bar foo) baz)
(is (= 2 2))))
But when I unwind the last level of threading by running cruw
again, I get this, which is not indented properly:
(deftest example-tests
(testing "something"
(is (= 1 1))
(baz (bar foo))
(is (= 2 2))))
I get the same result if I start with the (-> foo bar baz)
version at the top of this post and I do crua
(unwind-all):
(deftest example-tests
(testing "something"
(is (= 1 1))
(baz (bar foo))
(is (= 2 2))))
Maybe I'm just not understanding how this feature works, but I can't seem to get it to do anything except for throw this error:
Namespaced keywords not supported !
I was able to get cref
(extract fn) to work, FWIW.
All of sudden this error message started appearing for CCleanNS
command: Error: [object Object] is not ISeqable
for every single namespace. Any idea?
Given a form like this:
(is (= (pitch/hz->midi 7.95) 0))
The thread commands do not correctly indent the resulting forms:
;; crtf (thread-first-all)
(-> 7.95
pitch/hz->midi
(= 0)
is)
;; crtl (thread-last-all)
(->> 0
(= (pitch/hz->midi 7.95))
is)
;; crtt (thread-last)
(->> (= (pitch/hz->midi 7.95) 0)
is)
;; crth (thread)
(-> (= (pitch/hz->midi 7.95) 0)
is)
This is sort of similar to #21, though I'm not sure if it's technically related or not.
If I have this form:
(let [advertiser (-> advertiser
(unparse-custom-fields :rtbcustomfields))]
(if (zero? id)
(api-client/create-advertiser! (api-key) advertiser)
(api-client/update-advertiser! (api-key) advertiser)))
And I move my cursor to the (zero? id)
form and do crml
, naming the binding id-zero?
, this is the result:
(let [advertiser (-> advertiser
(unparse-custom-fields :rtbcustomfields))
id-zero? (zero? id)]
(if id-zero?
(api-client/create-advertiser! (api-key) advertiser)
(api-client/update-advertiser! (api-key) advertiser)))
(This is with parinfer disabled. With parinfer enabled, it's worse because parinfer rearranges my parens based on the indentation.)
I use syntax folding for clojure (set fdm=syntax
). To get crrs to work I had to:
set foldlevelstart=99
and open all folds in the current file.I noticed that the folded blocks containing the symbol are changed in their entirety, instead of just the symbol being renamed.
Quick fix might be to do zv
before making changes, or to set & unset the foldlevelstart (freezing the fold state somehow?)
There's possibly a better way to alter the symbol though.
e.g. clojure.test/is used as is
will generate ({:name clojure.test, :type :ns})
as candidates.
This should result in adding [clojure.test :refer [is]]
instead of just [clojure.test]
, https://github.com/clojure-emacs/clj-refactor.el/blob/f5295df68955c23fffd60718039fd386d13c77f5/clj-refactor.el#L2687-L2708 may act as inspiration
Related to #2
Thanks to @markwoodhall for pointing this out on slack. neovim api has changed in a seemingly non-compatible way around neovim/neovim@1c22cab (possibly earlier). I've raised an issue upstream with node-host to track this neovim/node-host#17 .
Until then, I'm guessing neovim/neovim@e968d72#diff-dbc90d97de125c32609c02bc24e2cabf should be a safe-ish build point unfortunately I don't have the bandwidth to do a full bisect of the issue.
crcn
fails when using :let g:clj_refactor_prefix_rewriting = 0
Error:
Cannot read property 'call' of null
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.