emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Emacs development...


From: Arthur Miller
Subject: Re: Emacs development...
Date: Sat, 21 Aug 2021 16:07:40 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Konstantin Kharlamov <hi-angel@yandex.ru> writes:

> On Sat, 2021-08-21 at 16:50 +0900, Jean-Christophe Helary wrote:
>> 
>> 
>> > On Aug 21, 2021, at 16:16, Tassilo Horn <tsdh@gnu.org> wrote:
>> > 
>> > Jean-Christophe Helary <lists@traduction-libre.org> writes:
>> > 
>> > Hi Jean-Christophe,
>> > 
>> > > Right now, I use C-h f to find the function definitions and move
>> > > around the code.
>> > 
>> > That, and also M-. on a function call or variable will bring you to its
>> > definition.
>> 
>> Thank you.
>> 
>> Sorry for this very basic question, what's the best way to navigate back to
>> where I was ?
>
> Seems to me, you don't have a workflow yet for development in general through
> Emacs. Because questions like "how to go to definition" and "how to go back"
> aren't really specific to ELisp, it's something you'd use while working with
> pretty much any language, be it C, Python, Haskell, C++, Rust… The only 
> question
> you asked specific to ELisp is about debugging ELisp code.
>
> This is okay ofc, I'm just pointing it out because it might give you some 
> ideas on what to look for.
>
> There's a popular opinion that default Emacs keybindings aren't the best, and 
> people usually reconfigure some of them as they find appropriate.
>
> And there're many different workflows for code/text navigation in Emacs. For
> example, I personally prefer using Evil plugin (a vim-mode inside Emacs, but 
> it
> actually had more features than the actual vim), and using C-o, C-i in "normal
> mode" of Evil to go back and forth between locations in text. By default it 
> may
> switch buffers which I don't like, so I disabled that. "going to definition" I
> personally bound to "gd" in normal mode of Evil. And then, inside a single 
> file
> there are usually multiple specific places that are of interest to me, so I 
> set
> marks to them with (again, keybinding specific to Evil) "m1", "m2", "m3"…
> i.e. just enumerating them in an order I find interesting.
>
> There's also "avy" package for faster navigation within the visible text 
> portions.
>
> There are also Emacs "starter-kits" with lots of preconfigured stuff, e.g. 
> Doom
> Emacs I heard is very good (I never personally used it, because by the time it
> became popular I already had a personalized configuration, however people seem
> to like it).
>
> So, yeah, for things non-specific to ELisp development (which is so far was
> everything you mentioned except ELisp debugging), you just need to start 
> trying
> to do the development, and along the way to try to reflect "what I really 
> wish I
> was able to do right now". Stuff like autocompletion, seeing function help in 
> a
> minibuffer or elsewhere, going to definition… Whatever you think of, it is
> probably implemented in Emacs (with or without plugins), so you just try to
> search for it using your favorite search engine.

Another not-so-elisp-specific thing would be to learn how to use a
debugger.

He could also take a class of computer science, or an online course etc
:).

Otherwise for non mentioned tips yet, structure editing cal also be
helpful (paredit/smartparens/lispy). Lispy is very good for elisp 
development.

Also a remapping some of hard to hit key combos predefined by Emacs, and
addign few trivial defs on top, for me makes a difference when evaluating
stuff. I have these following few small helpers:

#+begin_src emacs-lisp

;; From: https://emacs.wordpress.com/2007/01/17/eval-and-replace-anywhere/
(defun fc-eval-and-replace ()
  "Replace the preceding sexp with its value."
  (interactive)
  (backward-kill-sexp)
  (condition-case nil
      (prin1 (eval (read (current-kill 0)))
             (current-buffer))
    (error (message "Invalid expression")
           (insert (current-kill 0)))))

;; 
https://stackoverflow.com/questions/2171890/emacs-how-to-evaluate-the-smallest-s-expression-the-cursor-is-in-or-the-follow
(defun eval-next-sexp ()
  (interactive)
  (save-excursion
    (forward-sexp)
    (eval-last-sexp nil)))

;; this works sometimes
(defun eval-surrounding-sexp (levels)
  (interactive "p")
  (save-excursion
    (up-list (abs levels))
    (eval-last-sexp nil)))

(require 'popup)

(defun describe-thing-in-popup ()
  (interactive)
  (let* ((thing (symbol-at-point))
         (help-xref-following t)
         (description
          (save-window-excursion
            (with-temp-buffer
              (help-mode)
              (describe-symbol thing)
              (buffer-string)))))
    (popup-tip description
               :point (point)
               :around t
               :height 30
               :scroll-bar t
               :margin t)))

(defun value-at-point-in-popup ()
  (interactive)
  (let* ((thing (symbol-at-point))
         (value (and (boundp thing) (symbol-value thing))))
    (popup-tip (format "%s" value)
               :point (point)
               :around t
               :height 30
               :scroll-bar t
               :margin t)))

(defun last-sexp-in-popup ()
  (interactive)
  (let* ((value (eval-last-sexp nil)))
    (popup-tip (format "%s" value)
               :point (point)
               :around t
               :height 30
               :scroll-bar t
               :margin t)))

(defun next-sexp-in-popup ()
  (interactive)
  (let* ((value (eval-next-sexp)))
    (popup-tip (format "%s" value)
               :point (point)
               :around t
               :height 30
               :scroll-bar t
               :margin t)))

(defun surrounding-sexp-in-popup ()
  (interactive)
  (let* ((value (eval-surrounding-sexp 1)))
    (popup-tip (format "%s" value)
               :point (point)
               :around t
               :height 30
               :scroll-bar t
               :margin t)))

#+end_src

And I bind those like this:

#+begin_src emacs-lisp

(defkeys emacs-lisp-mode-map
"\C-c a" emacs-lisp-byte-compile-and-load
"\C-c b" emacs-lisp-byte-compile
"\C-c c" emacs-lisp-native-compile-and-load
"\C-c d" eval-defun
"\C-c e" eval-buffer
"\C-c i" reindent-buffer
"\C-c l" eval-last-sexp
"\C-c n" eval-next-sexp
"\C-c r" fc-eval-and-replace
"\C-c s" eval-surrounding-sexp)

#+end_src

So I can (often) just place my cursor somewhere in, before or after an
expression and eval it, as well as an expression before or after. It
reduces somewhat movements with cursor. For example I can place cursor
between a defun and a test for defun and eval prev/nect without moving
cursor etc. These are small trivial helpers, but I find them quite
useful sometimes.

Eldoc is also good to have when working with elisp.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]