Emacs helm completion: how to turn off persistent-help_line? - emacs

I'd like to use helm as a drop-in replacement for display-completion-list.
The only issue is that it displays this line on top, which I don't want:
C-z: I don't want this line here (keeping session).
Here's the code to illustrate:
(helm :sources `((name . "Do you have?")
(candidates . ("Red Leicester"
"Tilsit"
"Caerphilly"
"Bel Paese"
"Red Windsor"
"Stilton"))
(action . identity)
(persistent-help . "I don't want this line here"))
:buffer "*cheese shop*")
I've tried setting persistent-help to nil, or not setting it at all, but it
still appears. How can I turn it off?

The attribute helm-persistent-help-string comes with the library helm-plugin. If you do not load it you get no help string. If you need to load helm-plugin for some reason you can disable the function helm-persistent-help-string afterwards by:
(defadvice helm-persistent-help-string (around avoid-help-message activate)
"Avoid help message"
)
If you want to remove the gray header line completely you can do:
(defadvice helm-display-mode-line (after undisplay-header activate)
(setq header-line-format nil))
With defadvice you change the behavior of helm globally.
If you want to change helm-display-mode-line just temporarily for the execution of your helm command you could use:
(defmacro save-function (func &rest body)
"Save the definition of func in symbol ad-func and execute body like `progn'
Afterwards the old definition of func is restored."
`(let ((ad-func (if (autoloadp (symbol-function ',func)) (autoload-do-load (symbol-function ',func)) (symbol-function ',func))))
(unwind-protect
(progn
,#body
)
(fset ',func ad-func)
)))
(save-function helm-display-mode-line
(fset 'helm-display-mode-line '(lambda (source)
(apply ad-func (list source))
(setq header-line-format nil)))
(helm :sources `((name . "Do you have?")
(candidates . ("Red Leicester"
"Tilsit"
"Caerphilly"
"Bel Paese"
"Red Windsor"
"Stilton"))
(action . identity)
(persistent-help . "I don't want this line here"))
:buffer "*cheese shop*"))
(Note, that stuff like cl-flet does not work this way.)

Related

Emacs jump to next annotated words or phrases

When using Emacs, I notice that words or phrases in a buffer can be annotated or highlighted by many minor modes like hi-lock-mode, flyspell-mode, flycheck-mode...
Is there any uniform way to jump to the highlighted words or phrases created by all these minor modes? Specifically, is there any package or function support jumping to the next and previous highlighted phrases?
When using Eclipse, I can do it by pressing Ctrl-. and Ctrl-,. However, when switching to Emacs, so far, I haven't found an equivalent feature.
Developing a mode which aims to tackle that kind of tasks
https://github.com/andreas-roehler/werkstatt/tree/master/general-key
Facilitates the setting of a general command.
Than this command gets different bindings according to modes - which needs to be edited by hand once. Afterwards it allows to set/change a key at one place for all related/bound commands.
See for example inside
https://github.com/andreas-roehler/werkstatt/blob/master/general-key/general-key-python-mode.el
It's alpha still notably for the install process. Bug reports resp. feature requests welcome.
Not surprisingly, #Drew has answered something related to this.
You can programmatically use isearch with something like:
(defun foo (regexp)
(interactive (list (read-regexp "Regexp: ")))
(isearch-mode t t)
(let ((isearch-regexp nil))
(isearch-yank-string regexp)))
This will pull your previous regexp history, including those from hi-lock. I imagine it would be a fun exercise to modify this to use hi-lock-regexp-history.
If you use swiper, you can restrict the search candidates to lines with highlighted patterns by hi-lock-mode.
Here is a simple wrapper of swiper:
(require 'cl-lib)
(defun swiper-over-highlights-simple ()
(interactive)
(let ((original-swiper--candidates (symbol-function 'swiper--candidates)))
(cl-letf (((symbol-function 'swiper--candidates)
(lambda ()
(let ((pattern (mapconcat #'car hi-lock-interactive-patterns "\\|")))
(cl-remove-if-not (lambda (x) (string-match-p pattern x))
(funcall original-swiper--candidates))))))
(swiper))))
In addition, you can change ivy-read's preselect argument, which initializes the first matched line inside swiper.
The following fuction, modified from swiper, finds the closest next line with a highlighted pattern:
(defun swiper-over-highlights (&optional initial-input)
(interactive)
(let ((original-swiper--candidates (symbol-function 'swiper--candidates))
(pattern (mapconcat #'car hi-lock-interactive-patterns "\\|")))
(cl-letf (((symbol-function 'swiper--candidates)
(lambda ()
(cl-remove-if-not (lambda (x) (string-match-p pattern x))
(funcall original-swiper--candidates)))))
(let ((candidates (swiper--candidates)))
(swiper--init)
(setq swiper-invocation-face
(plist-get (text-properties-at (point)) 'face))
(let ((preselect
(save-excursion
(search-forward-regexp pattern nil t)
(let* ((current-line-value (current-line))
(candidate-line-numbers (mapcar (lambda (x) (cadr (text-properties-at 0 x)))
candidates))
(preselect-line-num (cl-find-if (lambda (x) (<= current-line-value x))
candidate-line-numbers)))
(- (length candidate-line-numbers)
(length (member preselect-line-num candidate-line-numbers))))))
(minibuffer-allow-text-properties t)
res)
(unwind-protect
(and
(setq res
(ivy-read
"Swiper: "
candidates
:initial-input initial-input
:keymap swiper-map
:preselect preselect
:require-match t
:action #'swiper--action
:re-builder #'swiper--re-builder
:history 'swiper-history
:extra-props (list :fname (buffer-file-name))
:caller 'swiper))
(point))
(unless (or res swiper-stay-on-quit)
(goto-char swiper--opoint))
(isearch-clean-overlays)
(unless (or res (string= ivy-text ""))
(cl-pushnew ivy-text swiper-history))
(setq swiper--current-window-start nil)
(when swiper--reveal-mode
(reveal-mode 1))))))))

Shortcut for inserting environments in `org-mode`

I'm using org-mode for organizing myself (very useful so far!). However, it is kind of annoying writting
#+begin_comment
...
#+end_comment
each time I'd like to insert an environment.
Question
Is there a shortcut to insert the #+begin_ and #+end_ for a given environment?
In the same way C-c C-o comment RET would insert
\begin{comment}
\end{comment}
in latex-mode.
Org has a facility called "Easy templates": http://orgmode.org/manual/Easy-Templates.html
A template for comment is missing but you can add it with:
(add-to-list 'org-structure-template-alist '("C" "#+begin_comment\n?\n#+end_comment"))
And use it by typing <C followed by TAB.
Alternatively, you could use yasnippet.
Now the corresponding template section is called Structure Template and the insertion sequence is invoked by C-c C-,. I didn't (require 'org-tempo) which is described to support insertion keys like <s TAB.
The comment environment is already defined in org-structure-template-alist. So the comment would be inserted by
C-c C-, C
It's still possible to add a user defined sequence by, for example,
C-c C-, [TAB|RET|SPC] src python :results output :session
delivering
#+begin_src python :results output :session
#+end_src
(emacs 25.2.2, org-mode 9.2)
You could have a look at "org-auctex-keys.el", a minor mode which I created to offer AUCTeX key bindings within Org documents.
In this case, you'd use C-c C-e to insert an environment (prompt to enter the environment name), as what AUCTeX does.
If you're interested, check it out at https://github.com/fniessen/org-auctex-key-bindings.
Not as elegant as the answer of Michael Markert but maybe more expandable.
1) You can select a region and put the block around it or you can just put the block at point.
2) Keyword expansion and history.
3) Keystrokes: C-c b
The command could be further expanded. E.g., for the src block the various switches like -n -r and export to files could be supported.
(defun list-major-modes ()
"Returns list of potential major mode names (without the final -mode).
Note, that this is guess work."
(interactive)
(let (l)
(mapatoms #'(lambda (f) (and
(commandp f)
(string-match "-mode$" (symbol-name f))
;; auto-loaded
(or (and (autoloadp (symbol-function f))
(let ((doc (documentation f)))
(when doc
(and
(let ((docSplit (help-split-fundoc doc f)))
(and docSplit ;; car is argument list
(null (cdr (read (car docSplit)))))) ;; major mode starters have no arguments
(if (string-match "[mM]inor" doc) ;; If the doc contains "minor"...
(string-match "[mM]ajor" doc) ;; it should also contain "major".
t) ;; else we cannot decide therefrom
))))
(null (help-function-arglist f)))
(setq l (cons (substring (symbol-name f) 0 -5) l)))))
(when (called-interactively-p 'any)
(with-current-buffer (get-buffer-create "*Major Modes*")
(clear-buffer-delete)
(let ((standard-output (current-buffer)))
(display-completion-list l)
(display-buffer (current-buffer)))))
l))
(defvar org-insert-block-hist nil
"History for command `org-insert-block'")
(defvar org-insert-block-hist/src:major nil
"History for major mode in org src blocks.")
(defvar org-insert-block-list (append org-protecting-blocks
'("comment" ""))
"List of block types offered as completion for command `org-insert-block'")
;; block_src switches: -n () -r (references) -l "((%s))" (label format) -k (keep labels)
(defvar org-insert-block-list-specials
"Assoc list of Commands for reading additional specification of org-blocks.")
(setq org-insert-block-list-specials
'(("src" . (concat " " (completing-read "Major mode:"
(list-major-modes)
nil nil
(car org-insert-block-hist/src:major)
'(org-insert-block-hist/src:major . 1)
)))))
(defun org-insert-block (bl &optional b e attributes)
"Put region between b and e into org-block of kind bl.
If b or e is nil then put org-block limiters around point.
The string attributes is inserted behind the string #+begin_... "
(interactive
(let ((usereg (use-region-p))
(blKind (completing-read "Input block kind (tab: completion, uparrow: history):"
org-insert-block-list nil nil (car org-insert-block-hist) '(org-insert-block-hist . 1))))
(list
blKind
(when usereg (region-beginning))
(when usereg (region-end))
(let ((spec (assoc blKind org-insert-block-list-specials)))
(when spec (eval (cdr spec)))
))))
(let ((begBlock (concat "\n#+begin_" bl attributes "\n"))
(endBlock (concat "\n#+end_" bl "\n")))
(if (and b e)
(save-restriction
(narrow-to-region b e)
(goto-char (point-min))
(insert begBlock)
(goto-char (point-max))
(insert endBlock)
(indent-region (point-min) (point-max)))
(let ((p (point)))
(insert endBlock)
(goto-char p)
(insert begBlock))
)))
(add-hook 'org-mode-hook '(lambda ()
(local-set-key (kbd "C-c b") 'org-insert-block)))

flet works, but with obsolete message; cl-flet does not work

I'm trying to temporarily turn off the yes-or-no-p within a function that is defined elsewhere and then restore things to the way they were. Using flet works, but creates a *compile-log* buffer telling me that it is obsolete and to use cl-flet instead. However, cl-flet doesn't seem to work with this attempt at defadvice -- i.e., nothing happens and the yes-or-no-p remains active. Any ideas on how to avoid the error message and make this work also?
(defun function-without-confirmation ()
(defadvice elmo-dop-queue-flush (around stfu activate)
(flet ((yes-or-no-p (&rest args) t)
(y-or-n-p (&rest args) t))
ad-do-it))
. . . .
(ad-unadvise 'elmo-dop-queue-flush)
)
I cannot take credit for the answer, because that was solved by wvxvw, so I'll put the relevant fix underneath the original question. The new macro is called lawlist-flet instad of flet, and the obsolete line has been commented out:
(defmacro lawlist-flet (bindings &rest body)
"Make temporary overriding function definitions.
This is an analogue of a dynamically scoped `let' that operates on the function
cell of FUNCs rather than their value cell.
If you want the Common-Lisp style of `flet', you should use `cl-flet'.
The FORMs are evaluated with the specified function definitions in place,
then the definitions are undone (the FUNCs go back to their previous
definitions, or lack thereof).
\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
(declare (indent 1) (debug cl-flet)
;; (obsolete "use either `cl-flet' or `cl-letf'." "24.3")
)
`(letf ,(mapcar
(lambda (x)
(if (or (and (fboundp (car x))
(eq (car-safe (symbol-function (car x))) 'macro))
(cdr (assq (car x) macroexpand-all-environment)))
(error "Use `labels', not `flet', to rebind macro names"))
(let ((func `(cl-function
(lambda ,(cadr x)
(cl-block ,(car x) ,#(cddr x))))))
(when (cl--compiling-file)
;; Bug#411. It would be nice to fix this.
(and (get (car x) 'byte-compile)
(error "Byte-compiling a redefinition of `%s' \
will not work - use `labels' instead" (symbol-name (car x))))
;; FIXME This affects the rest of the file, when it
;; should be restricted to the flet body.
(and (boundp 'byte-compile-function-environment)
(push (cons (car x) (eval func))
byte-compile-function-environment)))
(list `(symbol-function ',(car x)) func)))
bindings)
,#body))
And, here is the modified function that eliminates the error message relating to flet being obsolete.
(defun function-without-confirmation ()
(defadvice elmo-dop-queue-flush (around stfu activate)
(lawlist-flet ((yes-or-no-p (&rest args) t)
(y-or-n-p (&rest args) t))
ad-do-it))
. . . .
(ad-unadvise 'elmo-dop-queue-flush)
Here's how I'd recommend you do it:
(defvar stfu-inhibit-yonp nil)
(defadvice yes-or-no-p (around stfu activate)
(if stfu-inhibit-yonp (setq ad-return t) ad-do-it))
(defadvice y-or-n-p (around stfu activate)
(if stfu-inhibit-yonp (setq ad-return t) ad-do-it))
(defadvice elmo-dop-queue-flush (around stfu activate)
(let ((stfu-inhibit-yonp t))
ad-do-it))
Contrary to CL's flet this will make it clear (e.g. in C-h f yes-or-no-p) that something's going on with yes-or-no-p.

Context-sensitive font-locking in emacs

Basically, I'm trying to syntax highlight the following piece of coffeescript code the way I want it. Explanation of the syntax of coffeescript functions can be found here.
nameHere = (tstamp, moo, boo) ->
...
The names tstamp, moo and boo should be colored pink (and nothing else, not the commas and not the brackets) because they are parameters to a lambda function.
highOrderFun ((x) -> x * x) someList
Here it is the first x that is the parameter. Parameters can have default arguments:
class Foo
meth: (msg = "Hello", bar = "foo") ->
....
Default arguments can be variables themselves:
defColor = "red"
print = (msg, color = defColor) ->
...
So msg and color above should be highlighted, but not defColor. An even trickier case is functions with default arguments that themselves are functions. I think that is to hard for emacs' font-lock to highlight correctly, but I'm including it anyway:
funTakingFuns = (f1 = ((a, b) -> a*b), f2 = ((c, d) -> c/d)) ->
...
This appears to be pretty complicated to achieve in emacs because you want the highlighting to be context sensitive. I've read up on the documentation on font-lock but haven't been able to figure it out.
I'd be grateful if someone could show me what to set font-lock-defaults to make it syntax highlight the way I want it.
Update Showing more coffeescript syntax examples.
font-lock-keywords allows function values in the MATCHER field:
where MATCHER can be either the regexp to search for, or the function name to
call to make the search (called with one argument, the limit of the search;
it should return non-nil, move point, and set match-data appropriately if
it succeeds; like re-search-forward would).
So we need to write a function that would search for the next function argument in the buffer.
Something like this:
(defun coffee-match-next-argument (limit)
(let ((start (point)))
;; Look for the arrow.
(when (re-search-forward ") *->" limit t)
;; Save the position of the closing paren.
(let ((stop (point)))
(goto-char (match-beginning 0))
;; Go to the opening paren.
(goto-char (nth 1 (syntax-ppss)))
;; If we're before our initial position, go forward.
;; We don't want to find the same symbols again.
(when (> start (point))
(goto-char start))
;; Look for the next symbol until the arrow.
(or (re-search-forward "\\((\\|,\\) *\\(\\(\\sw\\|_\\)+\\)" stop 'mv)
(coffee-match-next-argument limit))))))
And the setup, to use with existing coffee-mode:
(font-lock-add-keywords
'coffee-mode
'((coffee-match-next-argument 2 font-lock-variable-name-face)))
You can also use this in font-lock-defaults, of course.
This will likely use some other color than pink, but that's easy to change.
This is more kind of a hack, it's far from optimal (as I am not familiar at all with coffeescript), but perhaps with a little tweaking yourself, you can get this done.
All the ingredients are there.
The triggering of the commands/functions are based on the assumption that you use coffee-mode.
If you do not, this is not a big trouble, you'll just have to hook these things differently.
Put the following line in your .emacs:
(eval-after-load 'coffee '(load "/PATH/custom-coffee-font-lock.el"))
You can just save the below text as a file, and it will:
(1) Font lock when you trigger coffee-mode
(2) Font lock current line when you type the ">" as part of "->"
(3) Allow to font-lock the buffer by running M-x coffee-init-font-lock
;;;; custom-coffee-font-lock
;; Firstly, create a new font for this.
(make-face 'font-lock-coffeescript-face)
(set-face-foreground 'font-lock-coffeescript-face "pink")
;; Next, one function that should be ran after a file is identified as
;; a coffeescript file. It will do the font-locking you want on
;; the whole buffer. It is also possible to run it manually.
(defun coffee-init-font-lock ()
(interactive)
(save-excursion
(goto-char 1)
(while (search-forward-regexp "=.+->" nil t)
(search-backward-regexp "(")
(forward-char 1)
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp ")" nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(move-end-of-line 1)))
)
;; This actually runs that function.
(coffee-init-font-lock)
;; This advice will be ran everytime you write something. It will check
;; whether "->" is before it, so when you type the final ">", it will
;; do the font locking for the current line (it also checks for your mode).
(defadvice self-insert-command (after coffee-font-lock activate)
(when (and (looking-back "->") (eq major-mode 'coffee-mode))
(save-excursion
(search-backward-regexp "(")
(forward-char 1)
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp ")" nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))))
)
(provide 'custom-coffee-font-lock)
;;; custom-coffee-font-lock.el
If you have any requests, let me know. Like I said, I do not use CoffeeScript, so this might throw huge errors your way. At the very least it should help with some basic ideas.
Result:

The mechanism iswtichb used to show completions

all.
I decided to hack iswitchb this morning, and found a confusing thing.
Usually,when we command iswitchb,we got someting in minibuffer like:
iswitch {buffer1,buffer2 ...}
What in braces is the completions, as we typing its number
is shrinking.
And I didn't find how iswitchb achieved this when hacking on
its code (sorry for my dullness ).
This is original iswitchb-read-buffer with doc-string ripped
off:
(defun iswitchb-read-buffer (prompt &optional default require-match
start matches-set)
(let
(
buf-sel
iswitchb-final-text
(icomplete-mode nil) ;; prevent icomplete starting up
)
(iswitchb-define-mode-map)
(setq iswitchb-exit nil)
(setq iswitchb-default
(if (bufferp default)
(buffer-name default)
default))
(setq iswitchb-text (or start ""))
(unless matches-set
(setq iswitchb-rescan t)
(iswitchb-make-buflist iswitchb-default)
(iswitchb-set-matches))
(let
((minibuffer-local-completion-map iswitchb-mode-map)
;; Record the minibuffer depth that we expect to find once
;; the minibuffer is set up and iswitchb-entryfn-p is called.
(iswitchb-minibuf-depth (1+ (minibuffer-depth)))
(iswitchb-require-match require-match))
;; prompt the user for the buffer name
(setq iswitchb-final-text (completing-read
prompt ;the prompt
'(("dummy" . 1)) ;table
nil ;predicate
nil ;require-match [handled elsewhere]
start ;initial-contents
'iswitchb-history)))
(if (and (not (eq iswitchb-exit 'usefirst))
(get-buffer iswitchb-final-text))
;; This happens for example if the buffer was chosen with the mouse.
(setq iswitchb-matches (list iswitchb-final-text)
iswitchb-virtual-buffers nil))
;; If no buffer matched, but a virtual buffer was selected, visit
;; that file now and act as though that buffer had been selected.
(if (and iswitchb-virtual-buffers
(not (iswitchb-existing-buffer-p)))
(let ((virt (car iswitchb-virtual-buffers))
(new-buf))
;; Keep the name of the buffer returned by find-file-noselect, as
;; the buffer 'virt' could be a symlink to a file of a different name.
(setq new-buf (buffer-name (find-file-noselect (cdr virt))))
(setq iswitchb-matches (list new-buf)
iswitchb-virtual-buffers nil)))
;; Handling the require-match must be done in a better way.
(if (and require-match
(not (iswitchb-existing-buffer-p)))
(error "Must specify valid buffer"))
(if (or (eq iswitchb-exit 'takeprompt)
(null iswitchb-matches))
(setq buf-sel iswitchb-final-text)
;; else take head of list
(setq buf-sel (car iswitchb-matches)))
;; Or possibly choose the default buffer
(if (equal iswitchb-final-text "")
(setq buf-sel (car iswitchb-matches)))
buf-sel))
And this is the part of iswitchb-read buffer,which I thought
is responsible for functioning completion mechanism.
(defun iswitchb-read-buffer (prompt &optional default require-match
start matches-set)
(let
(
(iswitchb-minibuf-depth (1+ (minibuffer-depth)))
)
;; prompt the user for the buffer name
(completing-read
prompt ;the prompt
'(("dummy" . 1)) ;table
nil ;predicate
nil ;require-match [handled elsewhere]
start ;initial-contents
'iswitchb-history)))
Eval
(iswitchb-read-buffer "Test: ")
resulting
Test: {buffer1,buffer2,...}
So, I think I'm right.
So,what confused me is how can sexp:
(iswitchb-minibuf-depth (1+ (minibuffer-depth)))
has effect on what echos in minibuffer. Comment this
sexp,or replace iswitchb-minibuffer-depth with another
variable, the completions will disappear.
Any advice?
This variable is used in iswitchb-entryfn-p which is called from iswitchb-minibuffer-setup
(defun iswitchb-minibuffer-setup ()
"Set up minibuffer for `iswitchb-buffer'.
Copied from `icomplete-minibuffer-setup-hook'."
(when (iswitchb-entryfn-p)
(set (make-local-variable 'iswitchb-use-mycompletion) t)
(add-hook 'pre-command-hook 'iswitchb-pre-command nil t)
(add-hook 'post-command-hook 'iswitchb-post-command nil t)
(run-hooks 'iswitchb-minibuffer-setup-hook)))
When iswitchb-minibuf-depth is null then iswitchb-entryfn-p is null and the setup is not done.
The iswitchb-minibuffer-setup is a hook which is added to the iswitchb-mode.
BTW, while this may not directly answer your question, this part of iswitchb's behavior is also provided by icomplete-mode (for the normal completion code).