How to debug? emacs lisp program behavior does not achieve the desired but the executing the same as command does? - elisp

In a test buffer in emacs with Spacemacs, I have the following (the problem is also described in the buffer content):
* Top Heading
** A subheading created by executing commands
M-x org-insert-heading
M-x org-do-demote
Below I tried to achieve the same with an elisp function:
*** A subheading created by executing an interactive elisp function still works
It also works. Here is the program:
(defun org-insert-subheading-relative ()
"Replacement of org-insert-subheading, as it requires to provide an argument,
which is not convenient to program."
(interactive)
(org-insert-heading)
(org-do-demote)
)
However, having the code segment below,
the (org-do-demote) would not work, in
the following code segment:
(progn
(goto-end-of-code-block)
(insert "\n")
(org-insert-heading)
(org-do-demote)
(insert block)
(hide-subtree)
)
What could be the cause of the problem?
Here is the related code not defined by standard emacs:
(defun goto-end-of-code-block ()
(re-search-forward "#\\+END_SRC.*$" nil t 1) ; no raising error
)

Related

How to always show inline images?

I'm trying to work with inline images (e.g. for plotting data by gnuplot), and have the problem: images always inserted as links by default. I need to do some keypresses to "force" emacs to show actual image inline, instead of just file link.
E.g. I start with gnuplot code:
#+BEGIN_SRC gnuplot :file plot.png
plot sin(x)
#+END_SRC
When I press C-c C-c on this code block, it runs, and shows me results as link to image file:
#+RESULTS:
[[file:plot.png]]
If I press C-c C-x C-v (org-toggle-inline-images) twice -- link does replaced with inline image
If I run M-x org-redisplay-inline-images -- again, link does replaced with image
If I run (org-display-inline-images t t) -- again, image is shown
and so on (those options were taken from Emacs org-display-inline-images and Inline images in org-mode questions)
But I don't want to press anything special: I want images to be displayed inline by default. I've found and tried following variables:
(setq org-startup-with-inline-images t) in .emacs config
#+STARTUP: inlineimages header
(setq org-display-inline-images t)
But neither got me the behavior I want. I'm puzzled -- do I want something so unnatural?
P.S. Im' using GNU Emacs v26.1 on MacOS X, org mode v9.1.9-65, if it matters
P.P.S. Although it seems like a bug in my emacs/orgmode version, and I'm yet to report it, but meanwhile I've found following trick: (add-hook 'org-babel-after-execute-hook 'org-display-inline-images 'append) (thanks to ob-ipython authors) -- it fixes issue for me right now. Maybe will be useful for somebody else
I can reproduce the problem with:
Org mode version 9.1.9 (release_9.1.9-65-g5e4542 # /home/xyz/.emacs.d/elpa/org-plus-contrib-20190415/)
Reproduction:
Start Emacs 26.3 with emacs -Q.
M-x load-library RET org RET
Add Gnuplot to org-babel-load-languages via M-x customize-option.
Load gnuplot.el
Open the Org file with the following content and press C-c C-c on the source block.
#+STARTUP: inlineimages
Some text.
#+BEGIN_SRC gnuplot :file plot.png :results graphics
plot sin(x)
#+END_SRC
I have a similar solution as you suggested in your question, but a bit more differentiated.
Re-displaying images in large Org documents can take some time. So I do it only if the source block has the results-parameter graphics:
(require 'subr-x)
(defun org+-babel-after-execute ()
"Redisplay inline images after executing source blocks with graphics results."
(when-let ((info (org-babel-get-src-block-info t))
(params (org-babel-process-params (nth 2 info)))
(result-params (cdr (assq :result-params params)))
((member "graphics" result-params)))
(org-display-inline-images)))
(add-hook 'org-babel-after-execute-hook #'org+-babel-after-execute)
#Tobias is the best answer. I have tweaked the #Tobias code to further optimize by bounding the re-display to the current subtree and setting the REFRESH parameter to t to redisplay only if necessary.
(require 'subr-x)
(defun org+-babel-after-execute ()
"Redisplay inline images in subtree if cursor in source block with :result graphics."
(when (org-in-src-block-p)
(let (beg end)
(save-excursion
(org-mark-subtree)
(setq beg (point))
(setq end (mark)))
(when-let ((info (org-babel-get-src-block-info t))
(params (org-babel-process-params (nth 2 info)))
(result-params (cdr (assq :result-params params)))
((member "graphics" result-params)))
(org-display-inline-images nil t beg end)))))
(add-hook 'org-babel-after-execute-hook #'org+-babel-after-execute)

How to load an executable in Scheme using the command line

I am using DrRacket and produced a file, hello.scm in emacs with the following content:
#! /usr/bin/env racket
;The first program
(begin
(display "Hello, World!")
(newline))
I then tried to compile the file at the terminal by using le$ racket hello.scm, and received this result:
Le-MacBook-Pro:~le$ racket hello.scm
default-load-handler: expected a `module' declaration, but found
something else
file: /Users/le/hello.scm
context...:
default-load-handler
standard-module-name-resolver
module-path-index-resolve
[repeats 1 more time]
module-declared?
Moreover, when I copy and paste the content of the emacs file into DrRacket and click Run, I receive the following message:
Module Language: only a module expression is allowed, either
#lang <language-name>
or
(module <name> <language> ...)
in: (begin (display "Hello, World!") (newline))
Interactions disabled.
What exactly is the problem?
The problem was solved by adding #lang racket at the top of the emacs file.

Emacs: open large files in external apps automatically

I would like to use Emacs as file manager too and open large file (in dired or speedbar) with xdg-open. Can I use defadvice for abort-if-file-too-large function and how to do it correctly?
Advising abort-if-file-too-large requires that it still raise an error even if it opens the file externally, otherwise find-file-noselect will still try to open the file. Also, you want to call the external program only when the operation type passed to abort-if-file-too-large indicates a file is being opened. Something like the following will work, though you might want to tweak the arguments to call-process to make it fit your scenario better:
(defun open-outside-emacs (orig-fun size op-type filename)
(if (not (string-equal op-type "open"))
(apply orig-fun size op-type filename)
(call-process "/usr/bin/xdg-open" nil 0 nil (expand-file-name filename))
(error "opened externally")))
(advice-add 'abort-if-file-too-large :around #'open-outside-emacs)

Emacs shell script mode hook

For some reason my shell script mode hooks do not get executed. Example in my .emacs:
(add-hook 'shell-script-mode-hook (lambda ()
(rainbow-delimiters-mode 1)))
causes the variables to be set, but the mode is not loaded for the opened script files. What is the proper way to hook here?
I use the default shell script mode (modeline says e.g. Shell-script[bash]). Do I have to hook for each shell type individually (sh, bash, zsh)? If yes can you please tell me how?
Thank you very much!
EDIT3:
It turned out to be due a conflict of textmate-mode with the skeleton-pair-insert in sh-mode (I tried to avoid the conflict by disabling textmate in sh-mode, which then left the sh-mood-hook aparatus in ruins. I've removed textmate-mode completely and use now the standard skeleton-pair approch globaly.
I'll accept phils answer - without him I'd probably not be able to debug this on my own.
EDIT2:
Thanks to phils, I think his comment takes us closer to solution. It's not a problem with rainbow-delimiters though. I removed all sh-mode-hook except your hello message one and restart Emacs. When I open a .sh file I get this:
Setting up indent for shell type bash
setting up indent stuff
Indentation variables are now local.
Indentation setup for shell type bash
File mode specification error: (void-function nil)
Note no "hello" message. The value of sh-mode-hook is:
(nil
(lambda nil
(message "hello")))
I think the problem is this first nil value - though I don't see that it would be set anywhere.
If I eval this:
(setq sh-mode-hook t)
(add-hook 'sh-mode-hook (lambda () (message "hello")))
I see the hello message, though after restart (I've put those lines in .emacs) it is gone again (the nil is again on top of the hook).
Any idea what to do to have active hook at setup?
EDIT1:
I've tried also:
(add-hook 'sh-mode-hook (lambda ()
(rainbow-delimiters-mode 1)))
with same negative result - not sure if this is relevant though...
shell-script-mode is an alias for sh-mode. I haven't checked, but I would suspect that only the hook variable for the 'real' function name is evaluated, so I think sh-mode-hook would be the one to use.
Anyhow, there's nothing broken about your syntax, so there may be something amiss with the use of (rainbow-delimiters-mode 1). For instance, you should be able to observe that the following works correctly:
(add-hook 'sh-mode-hook (lambda () (message "hello")))
FWIW, for hooks I recommend not using anonymous functions at all, simply because it's much easier to update your hook function if it is named (removing the old lambda expression from the variable before adding an updated one is just annoying in my books).
Try to remove ':
(add-hook 'shell-script-mode-hook (lambda () (rainbow-delimiters-mode 1)))

How do you load a file into racket via command line?

I have been trying to launch a racket program from the commandline (via 'racket') but have not been having success. According to the documentation (here http://docs.racket-lang.org/reference/running-sa.html#%28part._mz-cmdline%29) passing -f followed by a file should evaluate that file. However, I can't seem to get this to work. As a test, I made the following file:
;test.rkt
#lang racket
(define a 1)
Then, running it in racket (supposedly loading the file) and attempting to recall the value of a:
racket -f test.rkt -i
Welcome to Racket v5.1.1.
> a
reference to undefined identifier: a
My end goal is to be able to launch a different program from a shell script using the --main option combined with loading the definitions with -f to start up execution, just have become a bit baffled since I can't seem to get this trivial bit working.
Removing the #lang line works, but it means that your code is no longer a module, which makes it a pretty bad idea. To start racket on a given module file, all you need is to just run racket on the file, nothing else is needed. For example, put this in test.rkt:
#lang racket/base
(printf "Hi\n")
and just run it with racket test.rkt. If you want to have command-line flags, you can use (current-command-line-arguments) to get a vector of additional command-line arguments, but there's also the racket/cmdline library that makes it much easier to have standard kinds of flag processing. Here's an example for that:
#lang racket/base
(require racket/cmdline)
(define excitedness "")
(define mode "Hi")
(command-line
#:multi
[("-e" "--excited") "add excitedness levels"
(set! excitedness (string-append excitedness "!"))]
#:once-each
[("-b" "--bye") "turn on \"bye\" mode"
(set! mode "Bye")])
(printf "~a~a\n" mode excitedness)
and you can now run it with racket test.rkt <flags>. See also the Racket Guide's section on scripts for making your test.rkt even easier to run.
Finally, there is the --main approach that you've seen -- to use that, your module needs to provide a main function that receives all the command-line flags as arguments. For example:
#lang racket/base
(require racket/string)
(provide main)
(define (main . xs)
(printf "You gave me ~s flags: ~a\n"
(length xs) (string-join xs ", ")))
and to run it:
racket -t /tmp/y -m -- foo bar baz
The flag breakdown is: -t requires your module, -m causes racket to run your main function, and -- means that the following flags are all passed to your program. You can combine the flags like so:
racket -tm- /tmp/y foo bar baz
and that would be something that you'd usually put in your script trampoline as described in that guide section.
And, of course, this is all described in great details in the reference manual.
Remove the #lang racket header from your file:
;test.rkt
(define a 1)

Resources