Fork me on GitHub
#emacs
<
2024-01-05
>
macrobartfast06:01:53

I have an unmatched } somewhere deep in my project. The error does not provide a file or line number.

clojure.lang.ExceptionInfo: Unmatched delimiter ].
{:type :reader-exception, :ex-kind :reader-error}
...
It doesn't show up when I start my project but appears after it runs. It doesn't seem to appear after any event I can identify. Thoughts... strategies... sweet Emacs goodness?

elken07:01:52

M-x check-parens, write some elisp to enumerate every file in the project and call that but it may be simpler to just use clj-kondo

hiredman07:01:10

I think the reader built into the clojure runtime doesn't throw exceptions like that, that is coming from something using tools.reader (clojurescript uses that I believe)

macrobartfast07:01:45

I'll look into clj-kondo... not sure how to enumerate files.

macrobartfast07:01:57

I don't have any cljs in my project.

elken07:01:25

Could be edn too

macrobartfast07:01:55

from a missing [ to clj-kondo... truly the Hero's Journey.

hiredman07:01:11

What I mean is it isn't the clojure compiler / runtime throwing that error when it reads your code, it is something else reading a data file or reading your code throwing that error, any potentially some tooling you are using

hiredman07:01:33

The stacktrace might be useful to look at

macrobartfast07:01:07

clojure.lang.ExceptionInfo: Unmatched delimiter ]. {:type :reader-exception, :ex-kind :reader-error} at clojure.tools.reader.impl.errors$throw_ex.invokeStatic (errors.clj:34) clojure.tools.reader.impl.errors$throw_ex.doInvoke (errors.clj:24) clojure.lang.RestFn.invoke (RestFn.java:442) clojure.tools.reader.impl.errors$reader_error.invokeStatic (errors.clj:40) clojure.tools.reader.impl.errors$reader_error.doInvoke (errors.clj:36) clojure.lang.RestFn.invoke (RestFn.java:460) clojure.tools.reader.impl.errors$throw_unmatch_delimiter.invokeStatic (errors.clj:109) clojure.tools.reader.impl.errors$throw_unmatch_delimiter.invoke (errors.clj:108) clojure.tools.reader$read_unmatched_delimiter.invokeStatic (reader.clj:78) clojure.tools.reader$read_unmatched_delimiter.invoke (reader.clj:76) clojure.tools.reader$read_STAR_.invokeStatic (reader.clj:935) clojure.tools.reader$read_STAR_.invoke (reader.clj:917) clojure.tools.reader$read_delimited.invokeStatic (reader.clj:198) clojure.tools.reader$read_delimited.invoke (reader.clj:191) clojure.tools.reader$read_list.invokeStatic (reader.clj:209) clojure.tools.reader$read_list.invoke (reader.clj:205) clojure.tools.reader$read_STAR_.invokeStatic (reader.clj:935) clojure.tools.reader$read_STAR_.invoke (reader.clj:917) clojure.tools.reader$read_delimited.invokeStatic (reader.clj:198) clojure.tools.reader$read_delimited.invoke (reader.clj:191) clojure.tools.reader$read_list.invokeStatic (reader.clj:209) clojure.tools.reader$read_list.invoke (reader.clj:205) clojure.tools.reader$read_STAR_.invokeStatic (reader.clj:935) clojure.tools.reader$read_STAR_.invoke (reader.clj:917) clojure.tools.reader$read.invokeStatic (reader.clj:988) clojure.tools.reader$read.invoke (reader.clj:961) clojure.tools.namespace.parse$read_ns_decl.invokeStatic (parse.cljc:55) clojure.tools.namespace.parse$read_ns_decl.invoke (parse.cljc:39) clojure.tools.namespace.file$read_file_ns_decl.invokeStatic (file.clj:25) clojure.tools.namespace.file$read_file_ns_decl.invoke (file.clj:17) clojure.tools.namespace.file$files_and_deps$fn__9030.invoke (file.clj:63) clojure.core.protocols$fn__8249.invokeStatic (protocols.clj:168) clojure.core.protocols/fn (protocols.clj:124) clojure.core.protocols$fn__8204$G__8199__8213.invoke (protocols.clj:19) clojure.core.protocols$seq_reduce.invokeStatic (protocols.clj:31) clojure.core.protocols$fn__8234.invokeStatic (protocols.clj:75) clojure.core.protocols/fn (protocols.clj:75) clojure.core.protocols$fn__8178$G__8173__8191.invoke (protocols.clj:13) clojure.core$reduce.invokeStatic (core.clj:6886) clojure.core$reduce.invoke (core.clj:6868) clojure.tools.namespace.file$files_and_deps.invokeStatic (file.clj:62) clojure.tools.namespace.file$files_and_deps.invoke (file.clj:61) clojure.tools.namespace.file$add_files.invokeStatic (file.clj:81) clojure.tools.namespace.file$add_files.invoke (file.clj:74) clojure.tools.namespace.dir$update_files.invokeStatic (dir.clj:42) clojure.tools.namespace.dir$update_files.invoke (dir.clj:36) clojure.tools.namespace.dir$scan_files.invokeStatic (dir.clj:68) clojure.tools.namespace.dir$scan_files.invoke (dir.clj:45) clojure.tools.namespace.dir$scan_dirs.invokeStatic (dir.clj:92) clojure.tools.namespace.dir$scan_dirs.invoke (dir.clj:71) clojure.tools.namespace.dir$scan.invokeStatic (dir.clj:105) clojure.tools.namespace.dir$scan.doInvoke (dir.clj:94) clojure.lang.RestFn.applyTo (RestFn.java:139) clojure.core$apply.invokeStatic (core.clj:669) clojure.core$apply.invoke (core.clj:662) com.biffweb.impl.util.reload$refresh.invokeStatic (reload.clj:28) com.biffweb.impl.util.reload$refresh.invoke (reload.clj:27) clojure.lang.Atom.swap (Atom.java:51) clojure.core$swap_BANG_.invokeStatic (core.clj:2370) clojure.core$swap_BANG_.invoke (core.clj:2362) com.biffweb$eval_files_BANG_.invokeStatic (biffweb.clj:206) com.biffweb$eval_files_BANG_.invoke (biffweb.clj:202) com.tasktask$on_save.invokeStatic (tasktask.clj:41) com.tasktask$on_save.invoke (tasktask.clj:39) clojure.lang.Var.invoke (Var.java:384) com.biffweb.impl.misc$use_beholder$fn__22402$fn__22406.invoke (misc.clj:32) com.biffweb.impl.misc$use_beholder$fn__22402.invoke (misc.clj:32) nextjournal.beholder$fn$reify__19952.onEvent (beholder.clj:13) io.methvin.watcher.DirectoryWatcher.onEvent (DirectoryWatcher.java:402) io.methvin.watcher.DirectoryWatcher.runEventLoop (DirectoryWatcher.java:349) io.methvin.watcher.DirectoryWatcher.lambda$watchAsync$1 (DirectoryWatcher.java:232) java.util.concurrent.CompletableFuture$AsyncSupply.run (CompletableFuture.java:1764) java.util.concurrent.CompletableFuture$AsyncSupply.exec (CompletableFuture.java:1756) java.util.concurrent.ForkJoinTask.doExec (ForkJoinTask.java:295) java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec (ForkJoinPool.java:1016) java.util.concurrent.ForkJoinPool.scan (ForkJoinPool.java:1665) java.util.concurrent.ForkJoinPool.runWorker (ForkJoinPool.java:1598) java.util.concurrent.ForkJoinWorkerThread.run (ForkJoinWorkerThread.java:183) clojure.lang.ExceptionInfo: Unmatched delimiter ]. {:type :reader-exception, :ex-kind :reader-error} at clojure.tools.reader.impl.errors$throw_ex.invokeStatic (errors.clj:34) clojure.tools.reader.impl.errors$throw_ex.doInvoke (errors.clj:24) clojure.lang.RestFn.invoke (RestFn.java:442) clojure.tools.reader.impl.errors$reader_error.invokeStatic (errors.clj:40) clojure.tools.reader.impl.errors$reader_error.doInvoke (errors.clj:36) clojure.lang.RestFn.invoke (RestFn.java:460) clojure.tools.reader.impl.errors$throw_unmatch_delimiter.invokeStatic (errors.clj:109) clojure.tools.reader.impl.errors$throw_unmatch_delimiter.invoke (errors.clj:108) clojure.tools.reader$read_unmatched_delimiter.invokeStatic (reader.clj:78) clojure.tools.reader$read_unmatched_delimiter.invoke (reader.clj:76) clojure.tools.reader$read_STAR_.invokeStatic (reader.clj:935) clojure.tools.reader$read_STAR_.invoke (reader.clj:917) clojure.tools.reader$read_delimited.invokeStatic (reader.clj:198) clojure.tools.reader$read_delimited.invoke (reader.clj:191) clojure.tools.reader$read_list.invokeStatic (reader.clj:209) clojure.tools.reader$read_list.invoke (reader.clj:205) clojure.tools.reader$read_STAR_.invokeStatic (reader.clj:935) clojure.tools.reader$read_STAR_.invoke (reader.clj:917) clojure.tools.reader$read_delimited.invokeStatic (reader.clj:198) clojure.tools.reader$read_delimited.invoke (reader.clj:191) clojure.tools.reader$read_list.invokeStatic (reader.clj:209) clojure.tools.reader$read_list.invoke (reader.clj:205) clojure.tools.reader$read_STAR_.invokeStatic (reader.clj:935) clojure.tools.reader$read_STAR_.invoke (reader.clj:917) clojure.tools.reader$read.invokeStatic (reader.clj:988) clojure.tools.reader$read.invoke (reader.clj:961) clojure.tools.namespace.parse$read_ns_decl.invokeStatic (parse.cljc:55) clojure.tools.namespace.parse$read_ns_decl.invoke (parse.cljc:39) clojure.tools.namespace.file$read_file_ns_decl.invokeStatic (file.clj:25) clojure.tools.namespace.file$read_file_ns_decl.invoke (file.clj:17) clojure.tools.namespace.file$files_and_deps$fn__9030.invoke (file.clj:63) clojure.core.protocols$fn__8249.invokeStatic (protocols.clj:168) clojure.core.protocols/fn (protocols.clj:124) clojure.core.protocols$fn__8204$G__8199__8213.invoke (protocols.clj:19) clojure.core.protocols$seq_reduce.invokeStatic (protocols.clj:31) clojure.core.protocols$fn__8234.invokeStatic (protocols.clj:75) clojure.core.protocols/fn (protocols.clj:75) clojure.core.protocols$fn__8178$G__[qtp2038754704-20] INFO com.biffweb.impl.middleware - 18ms 200 get /app 8173__8191.invoke (protocols.clj:13) clojure.core$reduce.invokeStatic (core.clj:6886) clojure.core$reduce.invoke (core.clj:6868) clojure.tools.namespace.file$files_and_deps.invokeStatic (file.clj:62) clojure.tools.namespace.file$files_and_deps.invoke (file.clj:61) clojure.tools.namespace.file$add_files.invokeStatic (file.clj:81) clojure.tools.namespace.file$add_files.invoke (file.clj:74) clojure.tools.namespace.dir$update_files.invokeStatic (dir.clj:42) clojure.tools.namespace.dir$update_files.invoke (dir.clj:36) clojure.tools.namespace.dir$scan_files.invokeStatic (dir.clj:68) clojure.tools.namespace.dir$scan_files.invoke (dir.clj:45) clojure.tools.namespace.dir$scan_dirs.invokeStatic (dir.clj:92) clojure.tools.namespace.dir$scan_dirs.invoke (dir.clj:71) clojure.tools.namespace.dir$scan.invokeStatic (dir.clj:105) clojure.tools.namespace.dir$scan.doInvoke (dir.clj:94) clojure.lang.RestFn.applyTo (RestFn.java:139) clojure.core$apply.invokeStatic (core.clj:669) clojure.core$apply.invoke (core.clj:662) com.biffweb.impl.util.reload$refresh.invokeStatic (reload.clj:28) com.biffweb.impl.util.reload$refresh.invoke (reload.clj:27) clojure.lang.Atom.swap (Atom.java:51) clojure.core$swap_BANG_.invokeStatic (core.clj:2370) clojure.core$swap_BANG_.invoke (core.clj:2362) com.biffweb$eval_files_BANG_.invokeStatic (biffweb.clj:206) com.biffweb$eval_files_BANG_.invoke (biffweb.clj:202) com.tasktask$on_save.invokeStatic (tasktask.clj:41) com.tasktask$on_save.invoke (tasktask.clj:39) clojure.lang.Var.invoke (Var.java:384) com.biffweb.impl.misc$use_beholder$fn__22402$fn__22406.invoke (misc.clj:32) com.biffweb.impl.misc$use_beholder$fn__22402.invoke (misc.clj:32) nextjournal.beholder$fn$reify__19952.onEvent (beholder.clj:13) io.methvin.watcher.DirectoryWatcher.onEvent (DirectoryWatcher.java:402) io.methvin.watcher.DirectoryWatcher.runEventLoop (DirectoryWatcher.java:349) io.methvin.watcher.DirectoryWatcher.lambda$watchAsync$1 (DirectoryWatcher.java:232) java.util.concurrent.CompletableFuture$AsyncSupply.run (CompletableFuture.java:1764) java.util.concurrent.CompletableFuture$AsyncSupply.exec (CompletableFuture.java:1756) java.util.concurrent.ForkJoinTask.doExec (ForkJoinTask.java:295) java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec (ForkJoinPool.java:1016) java.util.concurrent.ForkJoinPool.scan (ForkJoinPool.java:1665) java.util.concurrent.ForkJoinPool.runWorker (ForkJoinPool.java:1598) java.util.concurrent.ForkJoinWorkerThread.run (ForkJoinWorkerThread.java:183)

hiredman07:01:10

Yeah, you are using some tool that is auto reloading your code. It is likely throwing that error because it is reloading in the middle of one of your edits when the code is not well formed

macrobartfast07:01:18

ah ok. btw the 200 get /appline may have been from me manually interacting with my webapp while this was spewing out.

macrobartfast07:01:39

Also, I've started trying to read more source code from libraries I use; I may have altered something in that.

macrobartfast07:01:33

But the idea that it's reloading when being edited makes a lot of sense partly because of the randomness of the appearance of the error.

m.q.warnock19:01:18

hey @U0X9N9ZK5 👋 Biff reloads (using beholder) when a file in your project is saved. Development-cycle preferences vary, especially among emacs users, so there are many potential ways to mitigate this kind of confusing situation. Personally, I have emacs set to save any time I switch away from a dirty buffer, but using paredit I basically never run into an unmatched paren/brace/bracket, and I have a habit of hitting C-c-k to compile any clojure namespace I just changed (cider needs to be connected), so I like the auto-reload behavior[1], but you might find it better to disable it (config.edn I think; my biff is a bit old), or auto-saving (if you have that enabled). 1. partly because it's usually redundant (after the C-c-k), but I actually have a little widget in my status bar (polybar) that shows me a red thumbs down if the latest beholder refresh failed, so I don't move on and get confused by a bug I introduced a while ago.

macrobartfast21:01:34

This is incredibly helpful! And on point since C-c-k is a nervous tic at this point for me. I saw an earlier post that mentioned your status bar and I may want to add that in myself soon.

vemv13:01:22

Can I use Magit as a time machine for a given file? I want to see how a file evolved over time. It would be fairly crucial that I can see e.g. 100 revisions of the file very quickly, so the keybinding workflow should be streamlined (e.g. hold or )

elken13:01:57

Technically, but there's also just https://github.com/emacsmirror/git-timemachine 😛

👀 3
vemv13:01:28

that was my plan B :) I could try it

elken13:01:41

Works great, I use it often

cjohansen14:01:39

git-timemachine was amazing! 🙏

🙌 1
aisamu14:01:00

Since you've asked about magit, there's magit-file-dispatch's navigation commands (`magit-blob-previous` and magit-blob-next, or Prev blob and Next blob on the transient).

til 1
vemv15:01:23

Awesome @U1UQEM078 - seems to do the job nicely! The other package seems a solid option as well, but if I can avoid extra deps, so much the better

jakemcc15:01:50

git-timemachine is great

vemv16:01:05

How to effectively browse git stashes with Magit? I see this buffer after M-x magit-stash l (list), but then hitting any of TAB, RET, v, 1, etc don't seem to show the diff of the stash under POINT What works for me once I see this buffer is to M-x magit-stash again, then hit v (show). But that seems excessively slow - I want to quickly browse the stashes. Surely I'm missing something or the keybinding map is broken somehow

jakemcc16:01:07

huh, in whatever setup I have going on, if I have my cursor on the line listing the stash and hit return, the diff pops up

jakemcc16:01:42

and that is consistent from either the magit-status page or magit-stash l

jakemcc16:01:32

and it looks like RET is bound to magit-stash-show

vemv16:01:27

hmm, I restarted Emacs, and RET worked exactly once. After a second attempt, it complains Buffer is read only

vemv16:01:56

I can M-x magit-stash-show over the git status stashes section though, and it will work every time So sounds like some sort of bug, or perhaps incompatibility with my personal pile o' hacks. Thanks for the hints!

jakemcc16:01:52

good luck 🙂

practicalli-johnny18:01:19

In my magic status buffer there is a stashes section and pressing Enter on one of them shows the contents, just as if viewing a commit in recent commits on the magic status buffer. I don't think Spacemacs does anything special, other that manage Evil key bindings for magic buffer

👍 1