Not offhand, but I looked it up and I think what you want is `key-description'. It prints key sequences, so e.g. (key-description "\370") evals to "M-x".
(defun insert-key-sequence (key-repr)
"Reads a literal key sequence from the user
and inserts a representation of it at point,
suitable for `global-set-key' or `local-set-key'."
(interactive "KKey sequence? ")
(prin1 key-repr (current-buffer))
(insert " "))
(add-hook 'emacs-lisp-mode-hook
#'(lambda ()
(local-set-key "\C-ck" #'insert-key-sequence)))
(run-hooks 'emacs-lisp-mode-hook)
Unfortunately it doesn't seem to work for mouse chords. #define for_duration(seconds, body) \
{ \
pthread_t tid_task, tid_watcher; \
\
void* task(void* arg) { \
body ; \
pthread_cancel(tid_watcher); \
return NULL; \
} \
\
void* watcher(void* arg) { \
sleep((seconds)); \
pthread_cancel(tid_task); \
return NULL; \
} \
\
pthread_create(&tid_task, NULL, &task, NULL); \
pthread_create(&tid_watcher, NULL, &watcher, NULL); \
pthread_join(tid_task, NULL); \
}
Use as: for_duration(10, {
while (true) {
printf("Infinite loop! where is your Godel now?\n");
}
});
Or with single brace-less statements: for_duration(10, while (true) printf("something\n") );
Lexical scope is sane: int i = 0;
for_duration(10, {
while (true) {
printf("%d\n", i++);
}
});
My comparison isn't quite fair, because your threading library provides 'with-timeout', while pthreads doesn't. If you factored this out, say with a signature like: void with_timeout(unsigned int seconds, void (*func)(void));
(in analogy to the common lisp function), then the macro part becomes just four lines: #define for_duration(seconds, body) { \
void func() { body ; } \
with_timeout((seconds), &func); \
}
I acknowledge that the lisp solution is rather more elegant. Also, my C macro is potentially dangerous because it is unhygenic. (It shadows outer declarations of 'task()', 'watcher()', 'tid_task', 'tid_watcher', and 'arg', in the body of 'body'.)