Emacs' org-batch-agenda exports wrong report - emacs

I want to print my todo list to shell with the following command:
emacs -batch -l ~/.emacs -eval '(org-batch-agenda-csv "t")'
The problem is that this command prints the agenda (like when using the "a" key) instead of the todo list. I haven't rebound any of this keys, so I don't know why this happens here.
Has anybody an idea what could be the problem?

I just tested this using Org-mode version 7.8.03 (release_7.8.03.321.gaac1c) and it worked as expected (for both org-batch-agenda-csv "t" and org-batch-agenda-csv "a"). What version are you using?

Related

Eshell can't find script on eshell path

My goal
I'm trying to add "/opt/bin" to the list of paths eshell uses to find scripts. So far I've tried to do this in three ways
Attempts so far
1) (setenv "PATH" (concat "/opt/bin:" (getenv "PATH")))
2) (eshell/addpath "/opt/bin:")
3) (add-to-list 'exec-path "/opt/bin")
The first attempt does add "/opt/bin" to eshell's path (it shows up as the first instance of "/opt/bin:" in the output of calling "which lein" below)
The second attempt also adds "/opt/bin" to eshell's path (it shows up as the second instance of "/opt/bin:" in the output of calling "which lein" below)
I actually have had "/opt/bin" added to my exec-path for a while. I believe I did this so that /opt/bin would be on my path when running the term command to start a shell, this seems to work fine but doesn't help eshell find commands there.
Failing attempts and temporary workaround
You can see in the eshell output below that even though a command, lein, is available on the path eshell recognizes eshell doesn't find the command. However if I create a symbolic link from a directory that is in eshells default path to a script in /opt/bin eshell is then able to find it.
Eshell output
~ $ which lein
which: no lein in (/opt/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/usr/local/sbin:/usr/sbin:/sbin:/opt/bin:)
~ $ l /opt/bin/ | grep lein
-rwxr-xr-x 1 kevin kevin 12538 2019-01-17 07:32 lein
~ $ sudo ln -s /opt/bin/lein /usr/local/bin/lein
[sudo] password for kevin:
~ $
~ $ which lein
/usr/local/bin/lein
I would prefer not to have to create symbolic links in /usr/local/bin/ just so that eshell can find scripts in my /opt/bin. Note even after restarting emacs it finds the symbolic link not the script in /opt/bin. This is occurring in a GUI instance of emacs-25 on linux mint debian (v9.3) edition.
Question:
How do I get eshell to actually check eshell path instead of the some default list of directories? Should I be updating a different path variable?
Looking at the source of eshell/addpath, it uses setq on eshell-path-env, which is a buffer local var. This means that if you use eshell/addpath, it has to be executed in the context of each eshell buffer. The best way to do this is to use a mode hook.
(defun jpk/eshell-mode-hook ()
(eshell/addpath "/opt/bin"))
(add-hook 'eshell-mode-hook #'jpk/eshell-mode-hook)
I'm not super familiar with Eshell, so I'm not going to say this is the best way, but it should work. eshell-path-env is set from (getenv "PATH") initially, so it's weird that setting PATH env var doesn't work (unless you're doing that after loading eshell).
One way:
Assuming you are running emacs in a terminal emulator or tty; then you can just add /opt/bin to your $PATH. Eshell uses your $PATH to find external commands. Not sure how it works for GTK version.

emacs --daemon with --batch and input file

I would like to create a script that simply cleans up the whitespace and tabs on several files in a folder for me. I have created a bash file with among other things:
emacsclient -t -e '(progn (prelude-cleanup-buffer-or-region) (save-buffer-kill-terminal))' $FILE
Now this doesn't seem to work as it interprets ALL the file arguments as functions to be run (so $FILE is executed as a function). (P.S. prelude-cleanup-buffer-or-region is from here)
Now what I really want appears to be --batch described here (since I don't actually want to display anything on the screen) but this isn't one of the options of emacsclient. The reason I want to use emacsclient rather than just using emacs --batch is that I have a lot of startup files so want all of this to stay loaded otherwise my script would take too long.
Does anyone have any advice on how to go about this?
Thanks in advance.
emacsclient -e means evaluate lisp forms, do not edit files
from the man page
-e, --eval
do not visit files but instead evaluate the arguments as Emacs
Lisp expressions.
I guess you could add a (find-file "file") to your list of forms to execute
I just tried this snippet -
/opt/local/bin/emacsclient -e '(progn (find-file "./tmpfoo")
(end-of-buffer) (insert "ffff") (save-buffer))'
and it edits the file silently like you'd expect.
you could use shell globbing and a script to expand an argument filename into the list of forms.
do not run with the -t switch either, -e doesn't expect to have a persistent editor window, and you don't need the kill-terminal. The client will just run your elisp and exit.
I think I would probably write a lisp function that took a filename argument, that I loaded into emacs at startup time, and then just call that with a filename via emacsclient,
e.g. FILENAME="somefile"; emacsclient -e "(now-do-my-thing $FILENAME)"

How to stop Emacs from rendering junk characters in shell?

In my emacs shell, I see this output:
^[[J~% echo $PS1
%2c%%
On my other machine, this stuff doesn't show up at all. Can anyone suggest a reason why and how to fix it?
It's related to your PS1 setting. Basically Emacs will not accept TOO fancy settings of PS1. I used the following code in ~/.bashrc to distinguish PS1 between xterm and other term simulators such as Emacs. You can give it a try.
case $TERM in
xterm)
export PS1='\[\e]0;\u#\h: \W\a\]\[\e[31;1m\]\w\n\[\e[0m\]'
;;
*)
export PS1='\[\e[31;1m\]\w\n\[\e[0m\]'
;;
esac

Running emacs from the command line and handling locked files

I'm using org-mode and am looking to export my agenda (example of an agenda) to a text file so that I can display it with conky. The org-mode manual features this command line example to do this:
emacs -batch -l ~/.emacs -eval '(org-batch-agenda "t")' | lpr
I've modified this like so:
emacs -batch -l ~/.emacs -eval '(org-batch-agenda "e")' \
> ~/org/aux/agenda-export.txt
I have this set as a cron job to run every 5 minutes. It works great unless I actually have emacs open. Then I noticed that the file agenda-export.txt was empty. In running this manually from the coammand line vs. through cron, I get this error (or similar depending on the files I have open):
...~/org/file.org locked by jwhendy (pid 10935): (s, q, p, ?)?
I was going to write a script to perhaps export to agenda-export-test.txt, then perhaps check for an empty file or no lines (wc -l == 0 maybe?). If true, leave the existing file alone and delete agenda-export-test.txt. If not, then move agenda-export-test.txt to agenda-export.txt.
But... when I try to run such a script, I'm met with the same emacs inquiry about whether to steal the lock, proceed, or quit. I'm fine with proceeding, as I don't think org-agenda does anything to the files and thus it wouldn't harm anything... but I don't know how to tell emacs to "force" or choose "proceed" if problems are encountered. I need something non-interactive.
So, to summarize, my thoughts were to try:
passing a --force option or similar to emacs to make it proceed at the pause
see if the exported tmp file has any lines and deal with it accordingly
tell emacs to run in "read only mode" (but I don't think it exists)
The main issue is that with cron, I'm not there to tell the process what to do, and so it just just make an empty file as the exported results. How can I handle this locked file business with a "blind" process like cron that can't respond?
I've tried asking the mailing list as well without a working outcome. [1] I wondered if someone here might have ideas.
[1] http://www.mail-archive.com/emacs-orgmode#gnu.org/msg45056.html
Have you tried copying file without using emacs?
put in your crontab:
cp ~/org/file.org /tmp/export.org && emacs -batch .... /tmp/export.org ..
A regular "cp" command should not copy emacs locks. Of course, once in a while you might get a damaged file if you save agenda just during cp command, but this should not be too bad.

Commands from .bashrc not available in Emacs

I have some aliases and functions defined in ~/.bashrc.
I start emacs from a terminal window using emacs -nw
When I execute M-x shell-command, the aliases and functions from ~/.bashrc are not available, but give a "command not found".
I've googled quite a bit but all the posts I come across say, if I understand them correctly, that ~/.bashrc is the place where this should work (rather than ~/.profile or ~/.bash_profile).
What am I missing?
Aliases are available only in interactive shell - a snapshot from bash man page:
Aliases are not expanded when the
shell is not interactive, unless the
expand_aliases shell option is set
using shopt
(see the description of shopt under SHELL BUILTIN COMMANDS below).
If you start Emacs from an interactive shell (in which .bashrc, etc. have executed), then the commands from your .bashrc should be available for both shell-command and shell, at least that's how it works for me.
But yeah as the other answer says, there is not real way to get a .bashrc environment in emacs. There are some documentation about a .emacs_bash file, but that never worked for me.
Okay misread your question here. If you are looking for functions and aliases instead of commands by changing paths in .bashrc, the non-interactiveness is the problem. I guess you can change the default argument to shell-command (take a look at explicit-bash-args) to make bash interactive, but that probably has unintended consequences.
The accepted answer correctly states that "aliases are available only in interactive shell".
This means that in order to load (rightly located indeed) aliases from ~/.bashrc, an interactive shell would have to be launched with Emacs's M-x shell-command (M-!).
To achieve this, add -i (interactive) switch to the M-x shell-command with:
(setq shell-command-switch "-ic")
Side Note, not Emacs related:
On some operating systems users would need to add the line source ~/.bashrc to ~/.bash_profile (or similar), since ~/.bashrc is not always auto-read by a system.