dash-docs-el / helm-dash

Browse Dash docsets inside emacs
511 stars 59 forks source link

Search results empty on first call #67

Closed otsaloma closed 8 years ago

otsaloma commented 9 years ago

I use helm-dash with buffer-local docsets and I have a key bound to helm-dash-at-point. Often the first time I call helm-dash-at-point the result list is empty. If I cancel that and call again the expected results show up. This happens often, but not always and with some docsets more often than others, but not consistently.

I looked at the code and if I understand correctly, registering the actual connection into helm-dash-connections under helm-dash-create-buffer-connections should happen only once per source per buffer, but it often seems to be done twice. Maybe it is related?

I currently call helm-dash-create-buffer-connections multiple times on after-change-major-mode-hook, which seems to work around the problem.

itsjeyd commented 9 years ago

@otsaloma I am experiencing the same issue with helm-dash. Would you mind sharing the code for the workaround?

otsaloma commented 9 years ago

Sure.


(defun my-css-mode-set-properties ()
  (setq-local helm-dash-docsets '("CSS")))

;; Buffer local docsets for each mode, CSS as an example.
(add-hook 'css-mode-hook 'my-css-mode-set-properties)

(defun my-helm-dash-connect ()
  (helm-dash-create-buffer-connections)
  (helm-dash-create-buffer-connections)
  (helm-dash-create-buffer-connections))

;; This is the workaround, runs after hooks that set the docsets to use.
(add-hook 'after-change-major-mode-hook 'my-helm-dash-connect t)
itsjeyd commented 9 years ago

@otsaloma Thanks!

Had a look at the helm-dash source myself, and it seems like the problem is caused by helm-dash-buffer-local-docsets.

Call graph:

helm-dash :arrow_right: helm-dash-create-buffer-connections :arrow_right: helm-dash-buffer-local-docsets :arrow_right: with-helm-current-buffer

helm-dash-buffer-local-docsets uses with-helm-current-buffer to get helm-dash-docsets for helm-current-buffer. For some reason, helm-current-buffer keeps pointing to the buffer helm-dash was called from previously, even after switching to another buffer in a different major mode. For example, if I

  1. Launch Emacs
  2. Call helm-dash from a sh-mode buffer (foo.sh)
    • Value of helm-current-buffer: #<buffer foo.sh> :+1:
  3. Switch to a python-mode buffer
  4. Call helm-dash again from the python-mode buffer (bar.py)
    • Value of helm-current-buffer: #<buffer foo.sh> :zap:

helm-dash will work fine right away in the sh-mode buffer, but for the buffer that's in python-mode, I'll have to cancel the command and issue it again to enable appropriate docsets. In the sh-mode buffer, helm-current-buffer is set to #<buffer foo.sh> (as you would expect), but in the python-mode buffer, helm-current-buffer isn't set to #<buffer bar.py>; it still points to foo.sh.

The net result of this is that helm-dash-create-buffer-connections will create connections for an outdated set of buffer-local docsets.


I am currently working around this by setting helm-current-buffer to an appropriate value in any function that sets up helm-dash for a specific major mode:

(defun helm-dash-python ()
  "Set up `helm-dash' for Python. Docsets: Python 2, Python 3."
  (setq-local helm-dash-docsets '("Python 2" "Python 3"))
  (setq helm-current-buffer (current-buffer)))

(add-hook 'python-mode-hook 'helm-dash-python)

In the original source, the issue could be fixed by doing (setq helm-current-buffer (current-buffer)) before calling helm-dash-create-buffer-connections in helm-dash and helm-dash-at-point. @areina Does that sound like a viable solution to you?

kidd commented 9 years ago

Wow, thanks for the very detailed investigation and report!

As a workaround, I think (setq helm-current-buffer (current-buffer)) is a viable solution.

pronobis commented 9 years ago

So, why not just fix it in helm-dash this way? Or just get docsets for (current-buffer)?

kidd commented 9 years ago

because I'm not sure writting to helm-current-buffer is not a huge hack... :/

pronobis commented 9 years ago

What I meant is to just get helm-dash-docsets from (current-buffer) and not from (helm-current-buffer). Basically, just like this:

(defun helm-dash-buffer-local-docsets ()
  "Get the docsets configured for the current buffer."
      (or (and (boundp 'helm-dash-docsets) helm-dash-docsets)
        '()))
davidshepherd7 commented 8 years ago

Related: if you set buffer-local docsets they will not be used until the second call to helm-dash in that buffer.

I've submitted a pull-request with a fix that works for me and doesn't require any scary hacks like writing helm-current-buffer.