zkry / p-search

Seach engine for Emacs
13 stars 1 forks source link

Unable to add query string prior: Wrong type argument: number-or-marker-p, nil #24

Closed swflint closed 2 days ago

swflint commented 2 days ago

Backtrace below.

Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil)
  transient--exit-and-debug(error (wrong-type-argument number-or-marker-p nil))
  +(7160120 nil)
  funcall(+ 7160120 nil)
  (setq x (funcall fn x prop-val))
  (let ((prop-val (p-search-document-property doc prop-key))) (setq x (funcall fn x prop-val)))
  (closure ((x . 7160120) (fn . +) (prop-key . size)) (_ doc) (let ((prop-val (p-search-document-property doc prop-key))) (setq x (funcall fn x prop-val))))((file "/home/swflint/Notes/dailies/20241126T083853--tuesd...") ((id file "/home/swflint/Notes/dailies/20241126T083853--tuesd...") (git-root closure ((function . p-search--file-git-root) (element . "/home/swflint/Notes/dailies/20241126T083853--tuesd...")) nil (funcall function element)) (size) (file-name closure ((function . identity) (element . "/home/swflint/Notes/dailies/20241126T083853--tuesd...")) nil (funcall function element)) (content closure ((function . p-search--file-text) (element . "/home/swflint/Notes/dailies/20241126T083853--tuesd...")) nil (funcall function element)) (title . "/home/swflint/Notes/dailies/20241126T083853--tuesd...")))
  maphash((closure ((x . 7160120) (fn . +) (prop-key . size)) (_ doc) (let ((prop-val (p-search-document-property doc prop-key))) (setq x (funcall fn x prop-val)))) #<hash-table equal 1735/2463 0xad28a1f>)
  (let* ((x init)) (maphash #'(lambda (_ doc) (let ((prop-val (p-search-document-property doc prop-key))) (setq x (funcall fn x prop-val)))) (p-search-candidates)) x)
  p-search-reduce-document-property(size 0 +)
  (p-search-query query-string #'(lambda (probs) (maphash #'(lambda (doc p) (p-search-set-score prior doc p)) probs) (p-search-calculate)) (hash-table-count (p-search-candidates)) (p-search-reduce-document-property 'size 0 #'+))
  (let* ((args (progn (or (progn (and (memq ... cl-struct-p-search-prior-tags) t)) (signal 'wrong-type-argument (list 'p-search-prior prior))) (aref prior 4))) (query-string (alist-get 'query-string args))) (p-search-query query-string #'(lambda (probs) (maphash #'(lambda (doc p) (p-search-set-score prior doc p)) probs) (p-search-calculate)) (hash-table-count (p-search-candidates)) (p-search-reduce-document-property 'size 0 #'+)))
  p-search--prior-query-initialize-function(#s(p-search-prior :template #s(p-search-prior-template :group "" :required-properties nil :name "text query" :input-spec ((query-string p-search-infix-string :key "q" :description "Query string")) :options-spec nil :initialize-function p-search--prior-query-initialize-function :result-hint-function p-search--text-search-hint :transient-key-string "qu") :results #<hash-table equal 0/65 0xdbb904d> :proc-or-thread nil :arguments ((query-string . "test") (importance . medium))))
  funcall(p-search--prior-query-initialize-function #s(p-search-prior :template #s(p-search-prior-template :group "" :required-properties nil :name "text query" :input-spec ((query-string p-search-infix-string :key "q" :description "Query string")) :options-spec nil :initialize-function p-search--prior-query-initialize-function :result-hint-function p-search--text-search-hint :transient-key-string "qu") :results #<hash-table equal 0/65 0xdbb904d> :proc-or-thread nil :arguments ((query-string . "test") (importance . medium))))
  (let* ((init-func (progn (or (progn (and (memq ... cl-struct-p-search-prior-template-tags) t)) (signal 'wrong-type-argument (list 'p-search-prior-template template))) (aref template 6))) (prior (p-search-prior-create :template template :arguments args :results (make-hash-table :test #'equal))) (init-res (funcall init-func prior))) (progn (or (progn (and (memq (type-of prior) cl-struct-p-search-prior-tags) t)) (signal 'wrong-type-argument (list 'p-search-prior prior))) (let* ((v prior)) (aset v 3 init-res))) prior)
  p-search--instantiate-prior(#s(p-search-prior-template :group "" :required-properties nil :name "text query" :input-spec ((query-string p-search-infix-string :key "q" :description "Query string")) :options-spec nil :initialize-function p-search--prior-query-initialize-function :result-hint-function p-search--text-search-hint :transient-key-string "qu") ((query-string . "test") (importance . medium)))
  (let* ((args (transient-args 'p-search-transient-dispatcher)) (prior (p-search--instantiate-prior template args))) (p-search--validate-prior prior args) (setq p-search-priors (append p-search-priors (list prior))) (if (> (hash-table-count (progn (or (progn (and ... t)) (signal 'wrong-type-argument (list ... prior))) (aref prior 2))) 0) (p-search-calculate) (p-search--reprint)))
  p-search-transient-prior-create(#s(p-search-prior-template :group "" :required-properties nil :name "text query" :input-spec ((query-string p-search-infix-string :key "q" :description "Query string")) :options-spec nil :initialize-function p-search--prior-query-initialize-function :result-hint-function p-search--text-search-hint :transient-key-string "qu"))
  (lambda nil (interactive) (p-search-transient-prior-create #s(p-search-prior-template :group "" :required-properties nil :name "text query" :input-spec ((query-string p-search-infix-string :key "q" :description "Query string")) :options-spec nil :initialize-function p-search--prior-query-initialize-function :result-hint-function p-search--text-search-hint :transient-key-string "qu")))()
  apply((lambda nil (interactive) (p-search-transient-prior-create #s(p-search-prior-template :group "" :required-properties nil :name "text query" :input-spec ((query-string p-search-infix-string :key "q" :description "Query string")) :options-spec nil :initialize-function p-search--prior-query-initialize-function :result-hint-function p-search--text-search-hint :transient-key-string "qu"))) nil)
  #f(compiled-function (fn &rest args) #<bytecode -0x206f25209927d07>)((lambda nil (interactive) (p-search-transient-prior-create #s(p-search-prior-template :group "" :required-properties nil :name "text query" :input-spec ((query-string p-search-infix-string :key "q" :description "Query string")) :options-spec nil :initialize-function p-search--prior-query-initialize-function :result-hint-function p-search--text-search-hint :transient-key-string "qu"))))
  apply(#f(compiled-function (fn &rest args) #<bytecode -0x206f25209927d07>) (lambda nil (interactive) (p-search-transient-prior-create #s(p-search-prior-template :group "" :required-properties nil :name "text query" :input-spec ((query-string p-search-infix-string :key "q" :description "Query string")) :options-spec nil :initialize-function p-search--prior-query-initialize-function :result-hint-function p-search--text-search-hint :transient-key-string "qu"))) nil)
  (lambda (fn &rest args) (interactive #f(compiled-function (spec) #<bytecode -0x16fe3c21efd25207>)) (apply '#f(compiled-function (fn &rest args) #<bytecode -0x206f25209927d07>) fn args))((lambda nil (interactive) (p-search-transient-prior-create #s(p-search-prior-template :group "" :required-properties nil :name "text query" :input-spec ((query-string p-search-infix-string :key "q" :description "Query string")) :options-spec nil :initialize-function p-search--prior-query-initialize-function :result-hint-function p-search--text-search-hint :transient-key-string "qu"))))
  apply((lambda (fn &rest args) (interactive #f(compiled-function (spec) #<bytecode -0x16fe3c21efd25207>)) (apply '#f(compiled-function (fn &rest args) #<bytecode -0x206f25209927d07>) fn args)) (lambda nil (interactive) (p-search-transient-prior-create #s(p-search-prior-template :group "" :required-properties nil :name "text query" :input-spec ((query-string p-search-infix-string :key "q" :description "Query string")) :options-spec nil :initialize-function p-search--prior-query-initialize-function :result-hint-function p-search--text-search-hint :transient-key-string "qu"))) nil)
  transient:p-search-transient-dispatcher::1969()
  funcall-interactively(transient:p-search-transient-dispatcher::1969)
  command-execute(transient:p-search-transient-dispatcher::1969)
zkry commented 2 days ago

Thanks for the bug report! So the error looks like it has occurred when your search query has ran and when trying to calculate the total file size, encountered a file that it was unable to calculate the size of.

After digging into this, I found that this error can occur in the following sequence of events:

A superficial fix when encountering this would be to run the command p-search-hard-refresh-buffer (G) which refreshes the candidate generator which removes the deleted file. I thinking of a better way to recover from this error or inform the user though. What I'm leaning towards is if any error occurs when calculating the size the the files, like the one above, recover from it and display a user error "Unable to process session candidates. This can occur if the document no longer exists. Run `p-search-hard-refresh-buffer' to refresh the candidate list." or something like it. I could also force remove the candidate and message something to the user. Definitely let me know your thoughts.

This touches the general problem of document's content changing after they've been added to the p-search session...

swflint commented 2 days ago

I think that seems reasonable, at least at first.

However, I have noticed this happens in a fresh, unused session, and the error remains even after performing the hard refresh (making it difficult/impossible to use at the moment.

zkry commented 2 days ago

oh, this definitely shouldn't be happening for fresh sessions as all candidate documents generated should have content and size. After looking into this some more, it appears commands like git ls-files will return deleted files, thus ruining the session from the start.

I added a check for the filesystem candidate generator to make sure that the file is actually on the filesystem and not to blindly trust git ls-files. Let me know if this fixes this problem!

swflint commented 2 days ago

That fixed it!

Is query-string interpreted as a regex or something else?

swflint commented 2 days ago

I hope you don't mind the issues -- I like the idea of this project quite a bit (it seems like a really helpful interface into Denote), and hope to make some additional contributions at some point.

zkry commented 2 days ago

Is query-string interpreted as a regex or something else?

The internal logic is kind of complicated and I'm planning on improving the UI to make it clearer what's actually being searched for. Essentially from each query term (space separated item in query-string) it performs a number of actual searches. Quoted terms are searched exactly as is. Unquoted terms are searched in a number of ways: if it is a compound word, a case insensitive search is performed for the whole term, the parts converted to snake, camel, kebab case, and each component individually each with reduced impact on the score. A non-composite term (e.g. frame) does a case-sensitive word-boundary search and a case insensitive search.

So for example, the query string frame window buffer-list "= (+ 1 2)" will spawn ten search processes: "\bframe\b", "frame", "\bwindow\b", "window", "buffer-list", "bufferList", "buffer_list", "buffer", "list", "= (+ 1 2)".

I'm planning on documenting this as well as making this expansion system more customizable so definitely let me know if you have any ideas about this.

And please do send any issue, question, or idea you might have, I greatly appreciate the feedback!