Coder Social home page Coder Social logo

helpful's Introduction

Helpful Coverage Status MELPA

Helpful is an alternative to the built-in Emacs help that provides much more contextual information.

screenshot

Usage

Install from MELPA, then call one of the following commands:

  • helpful-callable
  • helpful-function
  • helpful-macro
  • helpful-command
  • helpful-key
  • helpful-variable
  • helpful-at-point

If you want to replace the default Emacs help keybindings, you can do so:

;; Note that the built-in `describe-function' includes both functions
;; and macros. `helpful-function' is functions only, so we provide
;; `helpful-callable' as a drop-in replacement.
(global-set-key (kbd "C-h f") #'helpful-callable)

(global-set-key (kbd "C-h v") #'helpful-variable)
(global-set-key (kbd "C-h k") #'helpful-key)
(global-set-key (kbd "C-h x") #'helpful-command)

I also recommend the following keybindings to get the most out of helpful:

;; Lookup the current symbol at point. C-c C-d is a common keybinding
;; for this in lisp modes.
(global-set-key (kbd "C-c C-d") #'helpful-at-point)

;; Look up *F*unctions (excludes macros).
;;
;; By default, C-h F is bound to `Info-goto-emacs-command-node'. Helpful
;; already links to the manual, if a function is referenced there.
(global-set-key (kbd "C-h F") #'helpful-function)

Ivy users can use Helpful with counsel commands:

(setq counsel-describe-function-function #'helpful-callable)
(setq counsel-describe-variable-function #'helpful-variable)

Features

Source code

screenshot

Helpful will try really hard to show the source code. It shows the source code for interactively defined functions (unlike the built-in Help) and falls back to the raw sexp if no source is available.

View Callers

screenshot

Helpful will show you where a function is being called!

Prettier Docstrings

screenshot

Docstrings in helpful:

  • Highlight the summary (the first sentence)
  • Include cross-references to other functions/variables
  • Linkify references to Info nodes
  • Hide superfluous punctuation

screenshot

If a symbol is also documented in the Info manual, helpful will provide a link to the relevant section too.

Symbol Properties

screenshot

Helpful will show you the properties that have been applied to the current symbol. This provides visibility of features like edebug or byte-code optimisation.

Helpful will also highlight any symbol aliases.

Describe Commands

Helpful provides a separate helpful-command function, for when you just want to view interactive functions.

View Keymaps

screenshot

Helpful displays any keybindings that apply to interactive functions.

Integrated Tooling

screenshot

You can trace, debug or disassemble functions from inside Helpful. This is discoverable and doesn't require memorisation of commands.

Aliases

screenshot

If a function has multiple aliases in Emacs, Helpful will show all of the aliases defined.

Inspirations

This project has been heavily influenced by:

License

GPLv3+.

I am providing code in the repository to you under an open source license. Because this is my personal repository, the license you receive to my code is from me and not my employer.

helpful's People

Contributors

alexander-miller avatar celeritascelery avatar d125q avatar dakra avatar damiencassou avatar danielmartin avatar davidshepherd7 avatar erikarvstedt avatar hraban avatar iwahbe avatar jcs090218 avatar kisaragi-hiu avatar kljohann avatar lebensterben avatar mekeor avatar nagy avatar narendraj9 avatar nbarrientos avatar nbfalcon avatar nickdrozd avatar pythonnut avatar rhaps0dy avatar sound-logic avatar tarsius avatar vermiculus avatar wilfred avatar wyuenho avatar xeals avatar xuchunyang avatar yuhan0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

helpful's Issues

Add helpful-key

Please add a function that replaces describe-key and shows helpful-function for the pressed key.

Superfluous puncuation not removed

Helpful looks very nice.

I've noticed a problem. In the screenshots and in the description it states that: We solve the text-quoting-style debate by removing superfluous puncuation entirely.

But I see it is still there when I invoke it. If via M-x helpful-command + query-replace-regexp, you look at one example paragraph:

If ‘replace-regexp-lax-whitespace’ is non-nil, a space or spaces in the regexp
to be replaced will match a sequence of whitespace chars defined by the
regexp in ‘search-whitespace-regexp’.

Was this expected to be highlighted and not quoted?

Some function lookups using `helpful-function' yield `args-out-of-range'

When I do a lookup on certain functions I consistently get this error.

One example is org-edit-special:

Debugger entered--Lisp error: (args-out-of-range 0 10)
  replace-match(#("ffap" 0 4 (button (t) category helpful-describe-button-button symbol ffap)) t t "`ffap'" nil)
  replace-regexp-in-string("`\\_<\\(?:.\\|\n\\)+?\\_>'" #f(compiled-function (it) #<bytecode 0x1fdcbab>) "Call a special editor for the element at point.\n\nWhen at a table, call the formula editor with `org-table-edit-formulas'.\nWhen in a source code block, call `org-edit-src-code'.\nWhen in a fixed-width region, call `org-edit-fixed-width-region'.\nWhen in an export block, call `org-edit-export-block'.\nWhen at an #+INCLUDE keyword, visit the included file.\nWhen at a footnote reference, call `org-edit-footnote-reference'\nOn a link, call `ffap' to visit the link at point.\nOtherwise, return a user error." t t)
  helpful--format-docstring("Call a special editor for the element at point.\nWhen at a table, call the formula editor with `org-table-edit-formulas'.\nWhen in a source code block, call `org-edit-src-code'.\nWhen in a fixed-width region, call `org-edit-fixed-width-region'.\nWhen in an export block, call `org-edit-export-block'.\nWhen at an #+INCLUDE keyword, visit the included file.\nWhen at a footnote reference, call `org-edit-footnote-reference'\nOn a link, call `ffap' to visit the link at point.\nOtherwise, return a user error.")
  helpful-update()
  helpful-function(org-edit-special)
  funcall-interactively(helpful-function org-edit-special)
  call-interactively(helpful-function nil nil)
  command-execute(helpful-function)

Could it be related to some function being byte-compiled? Or is this some obvious error?

Make Helpful buffers behave better

I have essentially two problems with Helpful:

  1. Every time I check a definition using it, Helpful create some persistent buffers (at least 2), one for the searched function source file and one for the Helpful buffer itself.
    I think Helpful should use with-temp-buffer instead of find-file to visit the references (I found this article referencing this trade-off: http://ergoemacs.org/emacs/elisp_find-file_vs_with-temp-buffer.html), this way it wouldn't create a persistent buffer for the source file, and it would be faster.

  2. I can't configure Helpful to play nice with Shackle.
    This point probably spills over the first one (and that is why I didn't open two issues). Helpful is using switch-to-buffer to show its content. Unfortunately, this function does not use the display-buffer-alist and is harder to manage the window/buffers it creates. Also, if Helpful would use a function like display-buffer instead, it would create a persistent buffer for itself.

feature request: Make variable in helpful-variable buffer customizable

the old describe-variable function has this You can customize this variable. part, if the variable is declared with defcustom with a link to the customization buffer.
It would be nice to have something similar in helpful-variable.
One suggestion for this (just my personal preference) is to make the value editable inside the helpful-buffer, a bit like wdired or wgrep.
Thanks for this great package.

helpful-variable crashes for variables defined on C-source

Try to call helpful-variable for variable system-type.

It'll crash with the following error:

Debugger entered--Lisp error: (wrong-type-argument stringp C-source)
  string-match("\\`src/\\(.*\\.\\(c\\|m\\)\\)\\'" C-source)
  #f(compiled-function (symbol type library) "Search for SYMBOL's definition of type TYPE in LIBRARY.\nVisit the library in a buffer, and return a cons cell (BUFFER . POSITION),\nor just (BUFFER . nil) if the definition can't be found in the file.\n\nIf TYPE is nil, look for a function definition.\nOtherwise, TYPE specifies the kind of definition,\nand it is interpreted via `find-function-regexp-alist'.\nThe search is done in the source for library LIBRARY." #<bytecode>)(system-type defvar C-source)
  ad-Advice-find-function-search-for-symbol(#f(compiled-function (symbol type library) "Search for SYMBOL's definition of type TYPE in LIBRARY.\nVisit the library in a buffer, and return a cons cell (BUFFER . POSITION),\nor just (BUFFER . nil) if the definition can't be found in the file.\n\nIf TYPE is nil, look for a function definition.\nOtherwise, TYPE specifies the kind of definition,\nand it is interpreted via `find-function-regexp-alist'.\nThe search is done in the source for library LIBRARY." #<bytecode>) system-type defvar C-source)
  apply(ad-Advice-find-function-search-for-symbol #f(compiled-function (symbol type library) "Search for SYMBOL's definition of type TYPE in LIBRARY.\nVisit the library in a buffer, and return a cons cell (BUFFER . POSITION),\nor just (BUFFER . nil) if the definition can't be found in the file.\n\nIf TYPE is nil, look for a function definition.\nOtherwise, TYPE specifies the kind of definition,\nand it is interpreted via `find-function-regexp-alist'.\nThe search is done in the source for library LIBRARY." #<bytecode>) (system-type defvar C-source))
  find-function-search-for-symbol(system-type defvar C-source)
  find-variable-noselect(system-type C-source)
  helpful--definition(system-type nil)
  helpful--source(system-type nil)
  helpful-update()
  helpful-variable(system-type)
  funcall-interactively(helpful-variable system-type)
  call-interactively(helpful-variable)
  hydra--call-interactively-remap-maybe(helpful-variable)
  (progn (setq this-command 'helpful-variable) (hydra--call-interactively-remap-maybe (function helpful-variable)))
  hydra-describe/helpful-variable-and-exit()
  funcall-interactively(hydra-describe/helpful-variable-and-exit)
  call-interactively(hydra-describe/helpful-variable-and-exit nil nil)
  command-execute(hydra-describe/helpful-variable-and-exit)

Error when finding help for function `not`

Using spacemacs, a self-compiled emacs26 and helpful 20170829.1620.

Stacktrace:

Debugger entered--Lisp error: (error "Unexpected error whilst reading ~/Documents/git/emacs/src/data.c position 809: (invalid-read-syntax #)")
  signal(error ("Unexpected error whilst reading ~/Documents/git/emacs/src/data.c position 809: (invalid-read-syntax #)"))
  error("Unexpected error whilst reading %s position %s: %s" "~/Documents/git/emacs/src/data.c" 809 (invalid-read-syntax "#"))
  elisp-refs--read-all-buffer-forms(#<buffer  *refs-/home/a/Documents/git/emacs/src/data.c*-456857>)
  elisp-refs--read-and-find(#<buffer  *refs-/home/a/Documents/git/emacs/src/data.c*-456857> not elisp-refs--function-p)
  #f(compiled-function (buf) #<bytecode>)(#<buffer  *refs-/home/a/Documents/git/emacs/src/data.c*-456857>)
  elisp-refs--search-1((#<buffer  *refs-/home/a/Documents/git/emacs/src/data.c*-456857>) #f(compiled-function (buf) #<bytecode>))
  helpful--reference-positions(not t #<buffer  *refs-/home/a/Documents/git/emacs/src/data.c*-456857>)
  helpful-update()
  helpful-at-point()
  funcall-interactively(helpful-at-point)
  call-interactively(helpful-at-point nil nil)
  command-execute(helpful-at-point)

helpful-variable doesn't mention original variable value

When looking up variable information using describe-variable, both the current, and original assigned values are shown.

When using helpful-variable, only the current variable is shown.

I think helpful should follow the behavior in describe-variable and show both past and present values.

Add support for org links

Calling (org-store-link) in a normal buffer stores the link to the help buffer.
Would be nice if helpful would support this too.

Some info about usage would be nice, especially for newbies

Hi Wilfred,

great package and currently I am exploring the different functions helpful provide.

As an Emacs newbie myself it's sometimes hard to look at the source to discover the functionality of a package. So it would be nice to get some info about that in the README.

Especially stuff like how the different helpful functions could replace the builtins and how to do so in my emacs config file.

Support C-h S (info-lookup-symbol) in helpful-mode

C-h S (info-lookup-symbol) is for searching Info manual base on the Major mode, for helpful-mode, since it's related to Emacs, C-h S should search Emacs-related info manuals, like help-mode.

Not sure about the correct way, but I found the following works for me.

(info-lookup-maybe-add-help
 :mode 'helpful-mode
 :regexp "[^][()`'‘’,:\" \t\n]+"
 :other-modes '(emacs-lisp-mode))

(info-lookup-maybe-add-help
 :mode 'elisp-refs-mode
 :regexp "[^][()`'‘’,:\" \t\n]+"
 :other-modes '(emacs-lisp-mode))

changed from (in the end of info-look.el)

(info-lookup-maybe-add-help
 :mode 'help-mode
 :regexp "[^][()`'‘’,:\" \t\n]+"
 :other-modes '(emacs-lisp-mode))

Add to GNU ELPA ?

Well this package seems nice.

Seeing as it is for Emacs Lisp reference, are you planning to put it into the GNU ELPA archive?

Add link to info manual

For example, position-bytes has more information in the manual than in its docstring. The manual mentions that it's one-indexed.

No locations on defun's defined by macro's (e.g. use-package :defer t)

(originally at https://www.reddit.com/r/emacs/comments/6x2pnx/helpful_adding_contextual_help_to_emacs/dmddom3/ )
I'm not sure if this is a bug or just something that's impossible to do, but there's no location info on my-foo when you do emacs -Q and eval-buffer on the below file:

(package-initialize)
(use-package counsel
  :defer t
  :config
  (defun my-foo (x)
    (with-ivy-window
      (insert x))))
(require 'counsel)
(require 'helpful)
(helpful-function 'my-foo)

But if you do C-M-x on the defun, you will get location info.

Also, if you eval-buffer twice, you'll also get location info. So presumably it's the eval-after-load that doesn't bother with carrying around location, which makes sense.

Weird thing: If I remove the :defer t, I don't get location info from helpful, but when I afterwards try plain C-h f, it shows the location, and then doing helpful-function after that shows the location.

Fails while parsing files with parenthesis in comments

backward-up-list isn't smart enough to see that an opening parenthesis is inside comments. That causes helpful-function' to fail for functions like org-macro--collect-macros' as the source file contains comments with open parenthesis in them.

I am not sure how we can make sure that we stop moving up when we have reached the top-level as we cannot assume that a definition should always start at the zeroth column

helpful-command should have offer a "default" option of function under point

Currently when I use find-function, the default parameter is the current function under the point. This way I can call find-function and immediately press RET to describe the function under the point.

I think helpful should also assume the default to be the current word under the point ( but obviously let the user type a different argument if the wish ).

Also, thanks for the awsome pacakge. I'm very excited to hopefully fix the few remaining issues so that I can start using this package full time.

`C-h k` burns CPU for unknown binding

When using borg-queen, and binding C-h k to helpful-key, C-h k t takes all my CPU and doesn't produce anything until I kill it with C-g. M-x describe-key RET t produces

Symbol’s function definition is void: borg-queen-mark-for-checkout-tag

which is correct as t is bound to an unknown command.

"All references" links should jump to the reference

It would be an improvement if the links generated by "All references" jumped to the line of code where the reference is, something like how grep would behave. In fact, I'd like the interface to behave something like emacs's grep, where there are keybindings that allow you to quickly hop between all the calling instances.

(scan-error "Containing expression ends prematurely" 2 2)

  1. M-: (helpful-variable 'magit-branch-popup)
Debugger entered--Lisp error: (scan-error "Containing expression ends prematurely" 2 2)
  scan-sexps(4 -1)
  forward-sexp(-1)
  calculate-lisp-indent((1 2 13 nil nil nil 0 nil nil (2) nil))
  lisp-indent-line()
  cl--do-prettyprint()
  cl-prettyprint((:variable magit-branch-arguments :man-page "git-branch" :variables #f(compiled-function () #<bytecode 0x1b1dbe1>) :actions ((98 "Checkout" magit-branch-or-checkout) nil (67 "Configure..." magit-branch-config-popup) (108 "Checkout local branch" magit-branch-checkout) (115 "Create new spin-off" magit-branch-spinoff) (109 "Rename" magit-branch-rename) (99 "Checkout new branch" magit-branch-and-checkout) (110 "Create new branch" magit-branch) (120 "Reset" magit-branch-reset) (119 "Checkout new worktree" magit-worktree-checkout) (87 "Create new worktree" magit-worktree-branch) (107 "Delete" magit-branch-delete) (106 "Create branch from jira" magit-create-branch-from-jira-issue)) :default-action magit-checkout :max-action-columns 3 :setup-function magit-branch-popup-setup))
  helpful--pretty-print((:variable magit-branch-arguments :man-page "git-branch" :variables #f(compiled-function () #<bytecode 0x1b1dbe1>) :actions ((98 "Checkout" magit-branch-or-checkout) nil (67 "Configure..." magit-branch-config-popup) (108 "Checkout local branch" magit-branch-checkout) (115 "Create new spin-off" magit-branch-spinoff) (109 "Rename" magit-branch-rename) (99 "Checkout new branch" magit-branch-and-checkout) (110 "Create new branch" magit-branch) (120 "Reset" magit-branch-reset) (119 "Checkout new worktree" magit-worktree-checkout) (87 "Create new worktree" magit-worktree-branch) (107 "Delete" magit-branch-delete) (106 "Create branch from jira" magit-create-branch-from-jira-issue)) :default-action magit-checkout :max-action-columns 3 :setup-function magit-branch-popup-setup))
  helpful-update()
  helpful-variable(magit-branch-popup)
  eval((helpful-variable 'magit-branch-popup) nil)
  eval-expression((helpful-variable 'magit-branch-popup) nil nil 127)
  funcall-interactively(eval-expression (helpful-variable 'magit-branch-popup) nil nil 127)
  call-interactively(eval-expression nil nil)
  command-execute(eval-expression)

helpful-function doesn't show documentation

When I type M-x helpful-function RET shell-quote-argument, I don't get the documentation of the function, except through it's source code. Is that expected? I would like a properly formatted documentation of each function so I can use helpful-function as a drop-in replacement for C-h f.

helpful-command can't find use-package while helpful-macro can

The 3 functions behave differently:

  1. helpful-function shows many function containing the string "use-package" but not the macro itself
  2. helpful-macro only shows the use-package macro
  3. helpful-command shows only use-package-install-deferred-package and use-package-jump-to-package-form

Drop-in replacement for C-h f <describe-function>?

Would it be possible to provide a command that could be used instead of C-h f (describe-function)? The command would show a list of all functions in the system with a default for the function at point.

Screwed up formatting for new function

helpful-function sometimes overwrites buffers with strange output. This seems to happen for functions that are newly-defined.

GNU Emacs 25.2.1 (x86_64-apple-darwin13.4.0, NS appkit-1265.21 Version 10.9.5 (Build 13F1911)) of 2017-04-21

helpful: 20171116.1425

  1. Start Emacs with emacs -Q and load helpful (in the process of doing this, I also load use-package).

  2. Open a file called ~/bug-in-helpful.el. Define and evaluate the following function:

(defun bug-in-helpful ()
  "a bug in helpful.el"
  5)

Save the file. The screen should look like this:

helpful-1

  1. Call M-x helpful-function RET bug-in-helpful. For me, this causes a new window to open with the same buffer (bug-in-helpful.el). In the buffer (and hence in both windows), the text has been replaced with helpful-function output which is missing most information (it only has the source code, and that is in the form of a lambda).

helpful-2

Note that the buffer has been marked as having been changed.

  1. Undo the buffer change and close the extra window. Then call C-h f bug-in-helpful. This displays without any problems:

helpful-3

  1. Close the help window and repeat step 3. The strange behavior still occurs.

Add autoload tags

Rather than make the user inject things into their config, add autoload tags to the interactive functions so it'll load as soon as the user tries to use it (and the commands will tab complete too).

Don't propertize `foo bar'

This isn't a valid code snippet. See eval-defun for an example:

If acting on a `defun' for FUNCTION, and the function was
instrumented, `Edebug: FUNCTION' is printed in the echo area.  If not
instrumented, just FUNCTION is printed.

helpful-variable gets variable value too late

The value of the variable shown is taken too late after it has potentially already been changed by helpful.
The easiest way for me to explain this is with an example: using describe-variable on major-mode shows the major mode for the buffer, e.g. lisp-interaction-mode while using helpful-variable shows helpful-mode.

Adding imenu support

There's currently no imenu support. Below is an option, but relies on identifying headings by checking face and case. Not ideal, but does the job?

(defun helpful--create-imenu-index ()
  "Create an `imenu' index for helpful."
  (beginning-of-buffer)
  (let ((imenu-items '()))
    (while (progn
             (beginning-of-line)
             ;; Not great, but determine if looking at heading:
             ;; 1. if it has bold face.
             ;; 2. if it is capitalized.
             (when (and (eq 'bold (face-at-point))
                        (string-match-p
                         "[A-Z]"
                         (buffer-substring (line-beginning-position)
                                           (line-end-position))))
               (add-to-list 'imenu-items
                            (cons (buffer-substring (line-beginning-position)
                                                    (line-end-position))
                                  (line-beginning-position))))
             (= 0 (forward-line 1))))
    imenu-items))

(defun helpful-mode-hook-function ()
  "A hook function for `helpful-mode'."
  (setq imenu-create-index-function #'helpful--create-imenu-index))

(add-hook 'helpful-mode-hook
          #'helpful-mode-hook-function)

helpful-function does not show that a function is an alias

When using helpful-function the buffer does not show that the function is an alias of another one. For example M-x helpful-function RET yes-or-no-p RET does not say that it is an alias of y-or-n-p. I only saw a message in the echo area.

helpful-variable crashes for variables defined on C-source

Followup to #28. @Townk @Wilfred @dakra.

I can still reproduce the issue with M-x helpful-variable RET shell-file-name.

  • Emacs version: 26.0.90, compiled from emacs-26 branch
  • find-function-C-source-directory is properly set
  • M-x describe-variable RET shell-file-name works fine and I can click on the "C source code" link
  • helpful is at latest commit from master branch

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.