-
Notifications
You must be signed in to change notification settings - Fork 25
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
Clojure formatting problems with srefactor-lisp-format-buffer
#8
Comments
Thanks for the detailed report. Could you give the sample file above? |
I've fixed the indenting and |
Hi @tuhdo, the file I used for testing is https://github.com/jgralab/funnyqt/blob/master/src/funnyqt/in_place.clj. I use I've tested the latest version, and the |
Meanwhile waiting for it to be fixed, you can use |
Especially in a more complicated Lisp like Clojure. Now only the closing "}" on newline left for this case.
- Rename srefactor-elisp-symbol-to-skip to srefactor-lisp-symbol-to-skip. - We need to define a set of separate symbols for Clojure that override the symbols in common skip list. - Update the command to use and restore the skip list appropriately. This is getting tiresome. I need to create a macro for this.
These are solved so far: (ns funnyqt.in-place
- "In-place transformation stuff."
- (:require [clojure.tools.macro :as m]
- [funnyqt.generic :as g]
- [funnyqt.visualization :as viz]
- [funnyqt.utils :as u]
- [funnyqt.query :as q]
- [funnyqt.pmatch :as pm]
- [funnyqt.tg :as tg])
- (:import
- (javax.swing JDialog JButton AbstractAction WindowConstants BoxLayout
- JPanel JLabel JScrollPane JComboBox Action JCheckBox
- Box BorderFactory ImageIcon JComponent)
- (java.awt.event ActionEvent ItemEvent ItemListener)
- (java.awt Color GridLayout GridBagLayout GridBagConstraints)))
+ "In-place transformation stuff."
+ (:require [clojure.tools.macro :as m]
+ [funnyqt.generic :as g]
+ [funnyqt.visualization :as viz]
+ [funnyqt.utils :as u]
+ [funnyqt.query :as q]
+ [funnyqt.pmatch :as pm]
+ [funnyqt.tg :as tg])
+ (:import (javax.swing JDialog JButton AbstractAction WindowConstants BoxLayout JPanel JLabel JScrollPane JComboBox Action JCheckBox Box BorderFactory ImageIcon JComponent)
+ (java.awt.event ActionEvent ItemEvent ItemListener)
+ (java.awt Color GridLayout GridBagLayout GridBagConstraints))) (def ^{:dynamic true
- :doc "Only for internal use. See `as-pattern' macro."}
- *as-pattern* false)
+ :doc "Only for internal use. See `as-pattern' macro."
+ } *as-pattern* false) -(defmacro as-pattern
- "Performs the given rule application `rule-app` as a pattern.
+(defmacro as-pattern "Performs the given rule application `rule-app` as a pattern. -(defmacro letrule
- "Establishes local rules just like `letfn` establishes local fns.
+(defmacro letrule "Establishes local rules just like `letfn` establishes local fns.
Also see `rule` and `defrule`."
- {:arglists '([[rspecs] & body])}
+ {:arglists '
+ ([[rspecs]
+ &
+ body])
+ } `(binding [*as-pattern* true]
- ~rule-app))
+ ~rule-app)) It works well enough for Emacs Lisp, Common Lisp and Scheme. Clojure syntax is more complicated though so it's more difficult to handle. But good nevertheless, since if it can handle Clojure code it should handle Lisps fine. The most difficult one is the |
Good progress so far. I guess the main problem with Clojure is that its binding forms ( |
That's right. To solve this problem, I will add another custom variable, each element is a list of a head symbol (ilke |
@tsdh Now these are solved: (defn ^:private unrecur
"Replaces (recur ...) forms with (fnname ...) forms where *as-test* is bound to false.
Existing (fnname ...) forms are also wrapped by bindings of *as-test* to
false. Doesn't replace in nested `loop` or `fn` forms."
[fnname form]
- (u/prewalk (fn [el]
- (if (and (seq? el)
- (or (= (first el) 'recur)
- (= (first el) fnname)))
- `(binding [*as-test* false]
- (~fnname ~@(next el)))
- el))
- (fn [el]
- (and (seq? el)
- (let [x (first el)]
- (or (= x `clojure.core/loop)
- (= x `clojure.core/fn)))))
- form))
+ (u/prewalk
+ (fn [el]
+ (if (and (seq? el)
+ (or (= (first el) 'recur)
+ (= (first el) fnname)))
+ `(binding
+ [*as-test* false]
+ (~fnname ~@
+ (next el)))
+ el))
+ (fn [el]
+ (and (seq? el)
+ (let [x (first el)]
+ (or (= x `clojure.core/loop)
+ (= x `clojure.core/fn)))))
+ form)) + (try (f)
+ (catch Exception
+ e
+ (.printStackTrace e)))))) The above erroneous case of I think it's pretty good to use at a small scale like format an sexp tree, i.e. when you delete and add sexp and the layout becomes a bit messy, just run |
Now only the |
@tsdh what is this called in Clojure? {1 2, 3 4, 5 6, 7 8} |
Tu Do [email protected] writes:
It's a map literal, i.e., a hash-map where the keys are 1, 3, 5, and 7 |
@tsdh the trailing bracket: + :doc "Only for internal use. See `as-pattern' macro."
+ } *as-pattern* false) is solved. Now only the |
👍 |
If a line exceeds srefactor-newline-threshold, inserts a newline unless user executes oneline command.
The formatting is getting better over the past week. However, to implement this last case, it will take a while because now I don't have much time anymore. In addition, I want to make it right: instead of manually hard coded the form of sexp, I let user define and customize it like this, for example, the
which means that the second sexp of the form |
That looks like a good idea. (I don't get why there should be a ":" in a let-binding form, though.) And just to give you another challenge, this is also a valid let-form: (let [x 1
y 2 #_(this is a form not read by the reader)
z 17]
...) Any form in clojure can be "commented out" by prefixing it with |
So that it looks like keyword arguments and it's easier to quickly separate keywords and value with a glimpse. And thanks for the input. |
@tuhdo Sorry, I still don't get it. In a clojure Can you simply provide a clojure code snippet showing what you have in mind? |
@tsdh the template is not the actual code but formatting spec for a specific sexp in the form. Let's look at this again: (srefactor-deftemplate :major-mode clojure-mode
:form (let [:newline-gap 2 :align-regexp ":"]
)) The form (srefactor-deftemplate :major-mode common-lisp-mode
:form (cond
((:newline-gap 1))
)) It means that the conditional form of the cond will always be inserted with newline after the first sexp, no matter what. However, I've also thought of another style of formatting to handle cases like (srefactor-deftemplate :major-mode common-lisp-mode
:form (loop
for :s in :s :nl
for :s from :s to :s :nl
do :s
)) When Srefactor see (srefactor-deftemplate :major-mode clojure-mode
:form (let [:s :s :nl :align-regexp ":"]
)) It has the same meaning as above, and |
@tuhdo Yes, I understand that this is a template for srefactor and no clojure form. What I'm asking for is a sample clojure |
Ah I see. Proper example should be: (srefactor-deftemplate :major-mode clojure-mode
:form (:require [:s :s :nl :align-regexp ":"]
)) |
@tuhdo Hehe, you still didn't get me. The above template says that the (ns my.ns
(:require [foo.bar.baz :as baz]
[quux.bla :as bla])) so the BUT: you also specified If you wanted to align a (let [x 19
foo (do-it :x x)
z (some-other-expr)
foobar 1000]
...) However, I don't know if that's a good idea as default behavior. It's only nice if the |
Hi, @tuhdo , I guess the best would be for the behavior to be based on the clojure style guide. Best, |
Hi @tuhdo,
because of your posts on the Clojure and Emacs mailinglists accompanied by the nice demo gifs, I had to give
srefactor-lisp-format-buffer
a try (version 20150408.2109 from MELPA). While it seems to be really good for initially formatting a completely unformatted buffer, it introduces several formatting issues when being applied to a buffer which is already formatted perfectly according toclojure-mode
, i.e.,indent-region
with the whole buffer being marked wouldn't change anything.Here's are some diff hunks of stuff which I consider wrong or at least suboptimal:
:as
clauses lined up nicely, now they don't anymore.:require
vectors also used to line up and don't anymore.Putting the closing
}
of a map onto a new line seems as unidiomatic to me as putting closing parens on separate lines.A macro's docstring should be on a separate line IMO.
binding
should have the same indentation of its body aslet
. This might be caused bysrefactor-lisp-format-buffer
introducing TABs whereasclojure-mode
setsindent-tabs-mode
buffer-locally tonil
.The inner functions' bodies are indented wrongly. The first body form should start below the n in
fn
. (That the other contents look wrong here is again just the TABs issue.)One usually wants to have each
variable expression
pair on one line.That it adds a linebreak after the quote is strange. And usually, one prefers to have each
key value
pair in a map on the same line if there's enough space. Also, I don't see a reason why the argument list is split into three lines.The space between the
~@
and the following form is wrong. The same happens if you have~(stuff)
forms.Again, in a
loop
you want to have at least everyvariable expression
pair on the same line. If space permits it, I like having multiple pairs separated by comma on the same line, too. And there it's strange that the commas are placed on a new line.The variable to which the caught exception is bound should be on the same line as the catch.
I think most other changes I have are just duplicates of the issues above.
The text was updated successfully, but these errors were encountered: