org-mode: Number of items with a specific keyword - emacs

I am a bit new to org customization.
Is there a way to get the number of items with a TODO (or NEXT) keyword in an org document? I found this
https://metacpan.org/pod/distribution/App-OrgUtils/bin/count-org-todos
But I would rather have a solution that uses Emacs environment.
EDIT: This seems to do the trick. Not sure if there is a more elegant solution
(apply '+ (org-map-entries (lambda () 1) "/TODO|NEXT"))

You are right; org-map-entries is a great tool to accomplish what. You might try the alternate syntax per convention, but the form you have is nice and terse. I personally write that sort of query as:
(length (org-map-entries nil "+TODO=\"TODO\"|+TODO=\"NEXT\"" 'file))

Related

How to never expand yasnippets in comments and strings

I'd like to disable YASnippet expansion (for example, if) in comments and strings, but don't find how to do that in a generic way.
On The condition system, they say how to do it for Python, but I'd like to get it working for all prog-modes at once, and I'm not aware of any function which tests "in string/comment", independently of the language.
Is there still a way to do so?
Using lawlist's suggestion and adding it to prog-mode-hook:
(defun yas-no-expand-in-comment/string ()
(setq yas-buffer-local-condition
'(if (nth 8 (syntax-ppss)) ;; non-nil if in a string or comment
'(require-snippet-condition . force-in-comment)
t)))
(add-hook 'prog-mode-hook 'yas-no-expand-in-comment/string)

How to toggle between indentations on emacs?

emacs n00b here.
I face this problem at least once a week, I have a function call with its arguments one per line, but I'd like to reformat that such that all the arguments go to one line, i.e. I want to go from:
f(
x,
y,
z
);
to:
f(x, y, z);
what's the best way to do that?
In general, a simple approach to custom reformatting requirements is to create a keyboard macro which does the required editing in a generic way.
Abilities like moving across sexps & balanced expressions, searching and replacing within regions, and narrowing and widening the buffer all make this sort of thing pretty straightforward.
You can then give the macro a name, output its definition into your init file, and bind it to a key for future usage, all with no elisp knowledge required.
C-hig (emacs) Keyboard Macros RET
Edit: (for "Emacs n00bs" everywhere).
DO learn how to use keyboard macros. The learning curve is pretty shallow1, and they will pay amazing dividends in the long term.
Once you've learned how they work, force yourself to use them: Whenever you encounter a problem, say to yourself "Can I do this with a keyboard macro?" and if you think the answer is yes, then give it a try.
If you don't make yourself use them to begin with, you probably won't often think about them when use-cases crop up; but once they're a familiar part of your tool kit you'll find yourself using them very regularly.
1 Shallow, but probably longer than you expect, as you gradually come to realise just how much you can actually accomplish with the things. My own moment of clarity came when it occurred to me that I wasn't restricted to a single buffer, and correlating/extracting/transforming data from multiple buffers was something I could automate easily.
And of course macros can do anything that you can do, so their power grows with your own knowledge of Emacs.
Well, I doubt that it is the best way to do it but I wrote a function anyways. So here it goes:
(defun format-args-column-to-inline()
"Takes a c-style function whose arguments listed one per line and puts them inline."
(interactive)
(beginning-of-line 1)
(re-search-forward "(")
(forward-char -1)
(let ((start (point)))
(save-restriction
(save-excursion
(forward-sexp 1)
(narrow-to-region start (point)))
(while (re-search-forward "$")
(progn
(delete-forward-char 1)
(just-one-space 1))))))
Put your cursor somewhere in the first line and call the function.
Edit: Just saw that you wanted something slightly different. The output of this function is f( x, y, z ); [note the trailing and leading space of the argument list].

Common Lisp fuzzy-searchable function reference?

Is there a nice and friendly set of searchable documentation for ANSI Common Lisp anywhere? Preferably one that can be downloaded for use offline. I've Google but can only find static HTML pages that basically mean you need to know exactly what you're looking for.
I'm after something like http://erldocs.com/, where I can type something like "string" or "list" and all the matching functions come up instantly, for me to click on and browse easily.
Man pages are no use, since you need to know the exact function you need, while the searchable style allows you to discover functions without knowing them beforehand.
CLHS: Symbol Index
l1sp.org
In Slime, type C-cC-dh, a few chars of your search term, and then Tab to get a completion list.
Just type (apropos "term") in repl.
A downloadable version of the CLHS is available in info format:
ftp://gnu.org/gnu/gcl/gcl.info.tgz
Here's a handy emacs function to lookup the symbol under the point in the using F1:
(defun clhs-info ()
(interactive)
(ignore-errors
(info (concatenate 'string "(gcl) " (thing-at-point 'symbol)))))
(add-hook 'lisp-mode-hook
(lambda ()
(define-key lisp-mode-map [f1] 'clhs-info)))
You can do partial matching using Info-index rather than concatenation as well.

Insert yasnippet by name

I want to insert a specific yasnippet as part of a function in emacs-lisp. Is there a way to do that?
The only command that seems related is yas/insert-snippet, but it simply opens a popup with all the options and the documentation doesn't say anything about bypassing the popup by specifing the snippet name.
yas/insert-snippet is indeed just a thin wrapper around yas/expand-snippet for interactive use. However, the internal structures are... interesting. Judging from the source code the following does work for me when I want to expand the "defun" snippet in elisp-mode:
(yas/expand-snippet
(yas/template-content (cdar (mapcan #'(lambda (table)
(yas/fetch table "defun"))
(yas/get-snippet-tables)))))
As the author of yasnippet, I think you'd rather not rely on internal details of yasnippet's interesting data structures, which may change in the future. I would do this based on the documentation of yas/insert-snippet and yas/prompt-functions:
(defun yas/insert-by-name (name)
(flet ((dummy-prompt
(prompt choices &optional display-fn)
(declare (ignore prompt))
(or (find name choices :key display-fn :test #'string=)
(throw 'notfound nil))))
(let ((yas/prompt-functions '(dummy-prompt)))
(catch 'notfound
(yas/insert-snippet t)))))
(yas/insert-by-name "defun")
I'm just getting into yasnippet and I wanted to automatically insert one of my snippets upon opening a new file for certain modes. That led me to here but I've generated a slightly different solution. Providing yet another alternative: ("new-shell" is the name of my personal snippet for providing a new shell script template)
(defun jsm/new-file-snippet (key)
"Call particular yasnippet template for newly created
files. Use by adding a lambda function to the particular mode
hook passing the correct yasnippet key"
(interactive)
(if (= (buffer-size) 0)
(progn
(insert key)
(call-interactively 'yas-expand))))
(add-hook 'sh-mode-hook '(lambda () (jsm/new-file-snippet "new-shell")))
IMO, my solution is a tad less susceptible to breaking should yasnippet change dramatically.
This is 2022 now, so we can simply do the following :
(yas-expand-snippet (yas-lookup-snippet "name-of-your-snippet"))
See the documentation

Emacs, changing the default reftex citation

I'd like to modify emacs' behaviour when using reftex, so that after pressing 'C-c [' and choosing a citation format the default regex that comes up is one that will give me the citation I used last (the normal behaviour is to default to the word before the cursor, which is rarely of any use). I often cite the same source many times in a row, particularly when making notes on a single paper, so this would be a nice way to save a few keystrokes, and that's what we're all using emacs for, right :)
I know a little lisp, so I expect I'll end up working out a way to do this myself eventually, but I thought it'd be worth asking around to see if anyone else has done it first, no point re-inventing the wheel. (If you do want this feature, but also don't know how to achieve it, let me know and I'll drop you an email when I've done it.)
Thanks
redifining reftex-get-bibkey-default after you have loaded reftex (e.g. in your AUCTeX mode hook) should do it. The simplest would thus be:
(defun reftex-get-bibkey-default () (car reftex-cite-regexp-hist) )
However, this will destroy the default behaviour and wouldn't return anything if your history is empty, to keep the "previous word at point" behaviour from reftex in that case and then use the history, you can redefine it this way:
(defun reftex-get-bibkey-default () (if reftex-cite-regexp-hist
(car reftex-cite-regexp-hist)
(let* ((macro (reftex-what-macro 1)))
(save-excursion
(if (and macro (string-match "cite" (car macro)))
(goto-char (cdr macro)))
(skip-chars-backward "^a-zA-Z0-9")
(reftex-this-word)))
)
)
(WARNING: This is the first elisp code I've ever written which is more than 3 lines long, it could be terrible code. But it seems to work. But any comments on style or best practices would be most appreciated.)
I've worked it out! Just add the following code to .emacs it behaves exactly as I'd hoped. If you've not cited anything before then it behaves as normal, otherwise the default citation is the last used.
(defvar reftex-last-citation nil)
(defadvice reftex-citation (after reftex-citation-and-remember-citation activate)
"Save last citation to 'reftex-last-citation after running 'reftex-citation"
(setq reftex-last-citation ad-return-value))
(defadvice reftex-get-bibkey-default (around reftex-just-return-last-citation activate)
"If there is a 'reftex-last-citation then just return that instead of running 'reftex-get-bibkey-default"
(if reftex-last-citation
(setq ad-return-value reftex-last-citation)
ad-do-it))
Thanks for the help Mortimer, without your starting point I'd never had got here!
(Just wondering, is there any reason why your solution didn't use defadvice? As I implied above, elisp is all very new to me, so it'd be useful to know the best way of doing things.)