Giter VIP home page Giter VIP logo

Comments (14)

mathrick avatar mathrick commented on July 28, 2024 3

Turns out it's possible to make the button redefinition far more concise:

(let ((do-function (lambda (button)
		     (helpful-function (button-get button 'apropos-symbol))))
      (do-variable (lambda (button)
		     (helpful-variable (button-get button 'apropos-symbol)))))
  ;; :supertype only takes effect statically, at the time of
  ;; definition, so we can in fact redefine a button with itself
  ;; as its supertype
  (define-button-type 'apropos-function :supertype 'apropos-function 'action do-function)
  (define-button-type 'apropos-macro :supertype 'apropos-macro 'action do-function)
  (define-button-type 'apropos-command :supertype 'apropos-command 'action do-function)
  (define-button-type 'apropos-variable :supertype 'apropos-variable 'action do-variable)
  (define-button-type 'apropos-user-option :supertype 'apropos-user-option 'action do-variable))

from helpful.

agzam avatar agzam commented on July 28, 2024 2

I've been wondering for sometime now, how difficult would it be: to replace helm-persistent-action in helm-apropos with helpful-symbol?

from helpful.

piyo avatar piyo commented on July 28, 2024 1

EDIT: after a careful re-reading of this thread two years later, my comment is geared towards the subthread of helm and apropos and not apropos by itself. Please disregard if not interested in helm.

I keep helm-apropos as is, and add a persistent action as the default entry.
helm-add-action-to-source seems to be the key.

;;; helpful-in-helm ---- Add helpful action to helm-sources  -*- lexical-binding: t; -*-

;;; Usage:

;;; Activate with:
;; (use-package helpful
;;;  :init
;;;  (use-package helm
;;;    :init
;;;    (add-hook 'after-init-hook #'helpful-in-helm-activate)))

;;; ... then use M-x helm-apropos as normal. Press tab to see
;;; "Helpful" persistant action and press ENTER to select it.

;;; Commentary:

;;; Implementation: I don't understand how to add a persistent action
;;; to helm-elisp stuff, so I went with a advice-add style
;;; modification.

;;; Code:

(require 'helm-elisp)


(defvar helpful-in-helm--persistent-action-text
  "Helpful: View in helpful.")

(defvar helpful-in-help--helm-apropos-sources
  '(helm-def-source--emacs-commands
    helm-def-source--emacs-functions
    helm-def-source--eieio-classes
    helm-def-source--eieio-generic
    helm-def-source--emacs-variables
    helm-def-source--emacs-faces)
  "List of helm source generator functions that return a helm-source alist.
The command `helm-apropos' uses these sources. We will modify the
\"action\" key in the alist to include a helm persistent action
that will call `helpful'.

You should modify this if you modify `helm-apropos-function-list'.
FIXME: Should be linked instead of copied.")

;; command interface

;;;###autoload
(defun helpful-in-helm-activate ()
  "Activate the functionality.
See the docs in`helpful-in-help--helm-apropos-sources'.
FIXME: should be a minor mode?"
  (interactive)
  ;; first deactivate the advice, if any, then activate
  (helpful-in-helm--do-init :deactivate)
  (helpful-in-helm--do-init :activate))

(defun helpful-in-helm-deactivate ()
  "Deactivate the functionality.
See the docs in`helpful-in-help--helm-apropos-sources'."
  (interactive)
  (helpful-in-helm--do-init :deactivate))

;; lib (internals)

(defun helpful-in-helm--do-init (action)
  "Activate/deactivate based on ACTION."
  (mapcar
     (lambda (gensrcfun)
       (cond ((eql action :deactivate)
              (advice-remove gensrcfun #'helpful-in-helm--add-action-helpful))
             (t
              (advice-add gensrcfun :filter-return #'helpful-in-helm--add-action-helpful))))
     helpful-in-help--helm-apropos-sources))


(defun helpful-in-helm--add-action-helpful (orgfun-retval)
  "Add a persistent action to a helm source that will call helpful.

This advice function will :filter-return the original function's
return val ORGFUN-RETVAL."
  (prog1 orgfun-retval
    (let* ((src orgfun-retval)
           (insert-idx 0)) ;; insert at front
      (helm-add-action-to-source helpful-in-helm--persistent-action-text
                                 #'helpful-in-help--lookup-str-as-symbol
                                 src
                                 insert-idx))))

(defun helpful-in-help--lookup-str-as-symbol (str-sym)
  "Internal function to call `helpful-symbol'<f> on STR-SYM."
  (helpful-symbol (intern str-sym)))


(provide 'helpful-in-helm)
;;helpful-in-helm.el ends here

from helpful.

piyo avatar piyo commented on July 28, 2024 1

Having understood the usefulness of apropos-value and apropos-library which have no analogue in helpful.el, I would like to comment again, hopefully relevantly this time.

The apropos.el buttons call into functions that helpful.el does not have a replacement: describe-face, customize-group..., apropos-describe-plist, apropos-library.
The buttons also can call into functions helpful.el can replace which are describe-variable, describe-function. If the latter is desired, merely advising the functions would be sufficient (if overbearing). This is similiar to zenspider's comment: #25 (comment) without having to redefine buttons. Basically the below, but without the necessary ceremony of a global minor mode helpful-mode.

(advice-add 'describe-function :override #'helpful-function)
(advice-add 'describe-variable :override #'helpful-variable)
;; for completeness, not relevant to the discussion
(advice-add 'describe-command  :override #'helpful-callable)
(advice-add 'describe-key      :override #'helpful-key)
(advice-add 'describe-symbol   :override #'helpful-symbol)

However, for the former, first the helpful.el library would need to provide the appropriate functionality. Is there any discussion on the reporting interface desired, say for describe-face, customize-group..., apropos-describe-plist, apropos-library?

from helpful.

Alexander-Shukaev avatar Alexander-Shukaev commented on July 28, 2024 1

Should be using helpful-callable instead of helpful-function by the way.

from helpful.

colonelpanic8 avatar colonelpanic8 commented on July 28, 2024

@agzam Probably not hard to do with some advice trickery.

from helpful.

colonelpanic8 avatar colonelpanic8 commented on July 28, 2024

All of the sources involved just call out to describe-* e.g.

https://github.com/emacs-helm/helm/blob/33ea4c9f23d4ca20916c7e834ab4d6649122e4b5/helm-lib.el#L914

so I think it would just be a matter of overriding

helm-describe-function
helm-describe-variable
helm-describe-describe-face

from helpful.

Alexander-Shukaev avatar Alexander-Shukaev commented on July 28, 2024

Would it be possible to at least provide integration with standard apropos in a way that links that it offers would trigger helpful-* functions instead of describe-* ones. I know that we can advice-add them but perhaps that should be offered as a (global) mode by helpful itself?

from helpful.

zenspider avatar zenspider commented on July 28, 2024

I don't want to deal with helm. I would like to +1 @Alexander-Shukaev's suggestion or otherwise provide a simple apropos replacement.

It looks like it might be as simple as redefining some button types to replace their actions?

(define-button-type 'apropos-function
  'apropos-label "Function"
  'apropos-short-label "f"
  'face 'apropos-function-button
  'help-echo "mouse-2, RET: Display more help on this function"
  'follow-link t
  'action (lambda (button)
	    (describe-function (button-get button 'apropos-symbol))))

from helpful.

zenspider avatar zenspider commented on July 28, 2024

This seems to work but could use some extra helpful commands to complete it:

;; overrides in apropos to try to use helpful-* instead.

(require 'apropos)

(define-button-type 'apropos-function
  'apropos-label "Function"
  'apropos-short-label "f"
  'face 'apropos-function-button
  'help-echo "mouse-2, RET: Display more help on this function"
  'follow-link t
  'action (lambda (button)
            (helpful-function (button-get button 'apropos-symbol))))

(define-button-type 'apropos-macro
  'apropos-label "Macro"
  'apropos-short-label "m"
  'face 'apropos-function-button
  'help-echo "mouse-2, RET: Display more help on this macro"
  'follow-link t
  'action (lambda (button)
            (helpful-function (button-get button 'apropos-symbol))))

(define-button-type 'apropos-command
  'apropos-label "Command"
  'apropos-short-label "c"
  'face 'apropos-function-button
  'help-echo "mouse-2, RET: Display more help on this command"
  'follow-link t
  'action (lambda (button)
            (helpful-function (button-get button 'apropos-symbol))))

(define-button-type 'apropos-variable
  'apropos-label "Variable"
  'apropos-short-label "v"
  'face 'apropos-variable-button
  'help-echo "mouse-2, RET: Display more help on this variable"
  'follow-link t
  'action (lambda (button)
            (helpful-variable (button-get button 'apropos-symbol))))

(define-button-type 'apropos-user-option
  'apropos-label "User option"
  'apropos-short-label "o"
  'face 'apropos-user-option-button
  'help-echo "mouse-2, RET: Display more help on this user option"
  'follow-link t
  'action (lambda (button)
            (helpful-variable (button-get button 'apropos-symbol))))

;; (define-button-type 'apropos-face
;;   'apropos-label "Face"
;;   'apropos-short-label "F"
;;   'face '(font-lock-variable-name-face button)
;;   'help-echo "mouse-2, RET: Display more help on this face"
;;   'follow-link t
;;   'action (lambda (button)
;;             (describe-face (button-get button 'apropos-symbol))))
;;
;; (define-button-type 'apropos-group
;;   'apropos-label "Group"
;;   'apropos-short-label "g"
;;   'face 'apropos-misc-button
;;   'help-echo "mouse-2, RET: Display more help on this group"
;;   'follow-link t
;;   'action (lambda (button)
;;             (customize-group-other-window
;;              (button-get button 'apropos-symbol))))
;;
;; (define-button-type 'apropos-widget
;;   'apropos-label "Widget"
;;   'apropos-short-label "w"
;;   'face 'apropos-misc-button
;;   'help-echo "mouse-2, RET: Display more help on this widget"
;;   'follow-link t
;;   'action (lambda (button)
;;             (widget-browse-other-window (button-get button 'apropos-symbol))))
;;
;; (define-button-type 'apropos-plist
;;   'apropos-label "Properties"
;;   'apropos-short-label "p"
;;   'face 'apropos-misc-button
;;   'help-echo "mouse-2, RET: Display more help on this plist"
;;   'follow-link t
;;   'action (lambda (button)
;;             (apropos-describe-plist (button-get button 'apropos-symbol))))
;;
;; (define-button-type 'apropos-library
;;   'help-echo "mouse-2, RET: Display more help on this library"
;;   'follow-link t
;;   'action (lambda (button)
;;             (apropos-library (button-get button 'apropos-symbol))))

from helpful.

zenspider avatar zenspider commented on July 28, 2024

Poke

from helpful.

mathrick avatar mathrick commented on July 28, 2024

Poke too, this would be extremely handy. It's not trivially implemented by remapping things in a map, since apropos uses buttons (and maps push-button to RET), rather than mapping keys for lookup.

from helpful.

mathrick avatar mathrick commented on July 28, 2024

@piyo: sadly, override advice on those functions breaks some other things, most importantly company-box popups for elisp code. So redefining buttons is probably the hack to go with for now.

from helpful.

smsegal avatar smsegal commented on July 28, 2024

@mathrick Just chiming in to say that this has worked perfectly for me so far in my limited testing.

Would be great to see this merged directly into helpful.

from helpful.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.