1

I have written a Python function that takes a string input and performs a semantic search in my org-roam-directory and outputs the results in the following format after 2 seconds of computation:

[{'score': 0.9137982130050659, 'file:': '/Users/user/org/example.org', 'content': 'In this article, we introduce a new algorithm.'}, {'score': 0.9033759832382202, 'file:': '/Users/user/org/statistical_model.org', 'content': 'Statistical Model for Denoising.'}]

So it is essentially a list of dictionary with score, file location, and content. I can call the Python function in the command line by invoking: /Users/user/org/anaconda3/bin/python /Users/user/org/sentence-transformer.py "algorithm and model" and then it gives me the above printed output in the terminal.

I want to present this output in the Emacs minibuffer just like consult-ripgrep, and be able to select one of the options and open the file's content in another buffer.

I am currently trying to do this in Elisp as follows:

(defun open-file-from-python-script (input-string)
  (interactive "sEnter input string: ")
  (let* ((python-script-path "/Users/user/org/sentence-transformer.py")
         (output-string (shell-command-to-string (concat "/Users/user/org/anaconda3/bin/python " python-script-path " " input-string)))
         (output-list (json-read-from-string output-string))
         (file-path (completing-read "Select a file: " output-list :key #'cdr :predicate #'stringp)))
    (find-file file-path)))

However, it does not work and only outputs: Bad String Format: 10

I am not too familiar with Elisp so I was wondering how to do this properly?

3
  • emacs.stackexchange.com/tags/elisp/info
    – Drew
    Commented Jan 28, 2023 at 17:39
  • Can you clarify (in the question) what you mean by "does not work"?
    – Drew
    Commented Jan 28, 2023 at 17:39
  • It would be handy to add a notification about this 'follow up' question to your previous related question here. Anyway, json-read-from-string expects a json object as argument, so I guess you can best convert your dictionary to json, e.g. using json.dumps. Also make sure that your script outputs (i.e. prints) that json string. I'm not sure what causes that error message, maybe try M-x toggle-debug-on-error. Commented Jan 28, 2023 at 21:05

1 Answer 1

1

Using your example value, you can output (print) a 'valid' json structure using dumps() from the python json module.

Subsequently, because json-read-from-string returns a vector after parsing that output, you should use the 'generic' seq-map function to map over that vector.

By printing your example value via print(json.dumps(value)) from a test file named 'test.py', the files can be listed using the following code

(defun open-file-from-python-script ()
  (interactive)
  (let* ((output-list (json-read-from-string (shell-command-to-string "python test.py")))
         (files-list (seq-map #'cdadr output-list))
         (file-path (completing-read "Select a file: " files-list)))
    (find-file file-path)))

B.t.w. if your Emacs was compiled with libjansson, then you could use json-parse-string for parsing the json.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.