Z is a popular shell tool for jumping around commonly used directories. It uses "frecency" as a metric for determining which directory you intend to jump to based on keyword completions. So if I commonly cd to ~/.ssh, I can z ssh to jump there.
My question is how can I get the same functionality to work inside Emacs? That is, I want to be able to use ido-find-file or something similar but only have to type a few characters to jump to the directory I intended. Hopefully the solution can incorporate z itself so it makes use of the frecency metric already recorded by z.
I used z once but then I found fasd, which is inspired by autojump, z or v, and which I found much more powerful, if I remember well it is because:
it not only finds directories but also files
it can cd a result or use mplayer or your editor or another command
the completion is better, specially for zsh (again, if I remember well). The thing is, I constantly use the d alias to change directories.
Anyway, there's an emacs package to find files with it: https://github.com/steckerhalter/emacs-fasd
That's cool, but it isn't as interactive as I would like.
edit: then I had to update the package and:
(setq fasd-enable-initial-prompt nil) ;; don't ask for first query but fire fuzzy completion straight away.
There's a still a use case that isn't filled:
How to use fasd (or autojump or z) with completion in an emacs shell ?
I often use emacs' shell-mode. When I use my favorite alias d, it works, but I don't have completion at all. Here, zsh's completion is clearly missing. So I would like to use ido completion, for instance. I wrote a little function which you can easily adapt for z:
edit: finished the command and added ido completion triggered by TAB. Now type d (d followed by a space). If it keeps changing and if I manage to create a minor mode I'll post the link to my gitlab repo.
edit: I created a mode for this feature: https://gitlab.com/emacs-stuff/fasd-shell/tree/master
;; Use the fasd command line utility to change recently visited directories and more.
(defun fasd-get-path-list (pattern)
"call fasd with pattern and return the list of possibilities"
(s-split "\n" (s-trim (shell-command-to-string (format "fasd -l -R %s" pattern))))
)
(defun fasd ()
"If current shell command is `d something' call fasd"
(interactive)
(let* ((user-input (buffer-substring-no-properties (comint-line-beginning-position)
(point-max))))
(if (and (string= (substring user-input 0 2) "d ")) ;; todo: mapping to use something else than d and change directory.
(progn
;; get what is after "d "
(setq fasd-pattern (buffer-substring-no-properties (+ (comint-line-beginning-position) 2) (point-max)))
(setq fasd-command (concat "cd " (ido-completing-read "cd to: " (fasd-get-path-list fasd-pattern))))
(comint-kill-input)
(insert fasd-command)
(comint-send-input)
))))
;; Use TAB as in normal shell. Now we have even better completion than in zsh !
(define-key shell-mode-map (kbd "<tab>") 'fasd) ;; works like a charm :)
As a side note, I don't use it very often because I open shells in the directory of the current buffer with shell-here and shell-pop (a drop-down terminal like guake for gnome).
Within a project, I find projectile (Projectile) mode to be really helpful.
I use the standard keybindings C-p f or M-x projectile-find-file.
It does fuzzy matching on filenames and filters on recently used files.
Related
Editing a Bash script I want to assign a filename to a variable.
E.g. inputfile=foo.txt
With std. settings I can't complete the filename without first inserting a space after the '='.
Is there any solution to this?
First of all, comint-dynamic-complete has been obsolete since Emacs 24.1. The replacement function is completion-at-point.
Now, if you starting looking at what completion-at-point actually does in a shell script buffer, you'll eventually end up in comint anyway. In particular, the function comint--match-partial-filename looks promising for an explanation of the behavior you described.
If I read that correctly, the problem here is that "=" is considered a valid part of a filename, at least on POSIX-like systems (see variable comint-file-name-chars). So, the completion mechanism is trying to complete the filename "inputfile=/..." which it can obviously not find.
If you never use a "=" in your filenames (or you use it so rarely that the working completion outweighs other downsides), you may want to consider doing something like (setq comint-file-name-chars "[]~/A-Za-z0-9+#:_.$#%,{}-") in the shell script mode hook (if you are on a POSIX system; on Windows it would look slightly different).
Hope that helps.
You can use bash-completion assuming your not on windows. It just requires a slight modification to work in sh-mode since it uses a comint function to determine the current completion candidate.
I like this because, in addition to completing filenames there, it also will give you all the nice readline completion like command line switches, etc. Here is an example setup using company, but you could remove the company stuff, since all you really need is to add the modified completion-at-point function.
;; required packages: company bash-completion
(eval-when-compile
(require cl-lib))
;; locally redefine comint-line-beginning-position so bash-completion
;; can work in sh-mode
(defun sh-bash-completion ()
(cl-letf (((symbol-function 'comint-line-beginning-position)
#'(lambda ()
(save-excursion
(sh-beginning-of-command)
(point)))))
(let ((syntax (syntax-ppss)))
(and (not (or (nth 3 syntax)
(nth 4 syntax)))
(bash-completion-dynamic-complete)))))
;; put this in your sh-mode hook
(defun sh-completion-setup ()
;; add capf function
(add-hook 'completion-at-point-functions
'sh-bash-completion nil 'local)
(company-mode)
(make-local-variable 'company-backends)
;; use company completion-at-point
(delq 'company-capf company-backends)
(cl-pushnew 'company-capf company-backends)
(setq-local company-transformers
'(company-sort-by-backend-importance)))
(add-hook 'sh-mode-hook 'sh-completion-setup)
Emacs doesn't show breakpoints in text mode.
I tried integrating the suggestions here and here, but failed (I am not a lisp programmer).
I tried:
(require 'gdb-mi)
(setq default-text-properties '(foo 1111))
(defun set_breakpt_cmds ()
"set breakpoint and indicate on editor"
(interactive)
(gud-break)
(gdb-put-breakpoint-icon "false" (get-text-property 1 'foo)))
(global-set-key (kbd "<f12>") 'set_breakpt_cmds)
The resulting error is
Wrong number of arguments: (lambda (arg) "Set breakpoint at current line." (interactive "p") (if (not gud-running) (gud-call "dbstop \
at %l in %f" arg))), 0
Note: A similar issue is this (following this). However the solution there doesn't fit me because I would like to be able to call the fix from .emacs file. This way it is easier to duplicate my emacs configuration when I setup a new linux box.
Thanks
The error you get comes from the fact that gud-break expects an argument (which isn't used), so just use (gud-break 1).
The message reads as follow:
the error is of kind wrong number of arguments
when calling (lambda (arg) ...) (where we see that exactly one argument is expected)
and it was called with 0 arguments.
I am running bash terminal under Term: line run mode inside Emacs.
Often I want to go to beginning of a command (not beginning of line, which includes the prompt).
i.e. In below line, I 'd like to go to s (not p).
prompt> some command text here
May I know what is the key shortcut in doing so, if any?
C-cC-a (term-bol) is intended to do this. It works by moving to the beginning of the line, and then skipping forward past the prompt, as defined by the buffer-local term-prompt-regexp variable.
However the default value for that regex is just ^ (which therefore has no effect in this situation); so you would need to set it yourself. There are some useful examples in that variable's help text.
Some alternative options are:
Use term-char-mode instead (in which case C-a works).
You can switch to char mode with C-cC-k and back to line mode with C-cC-j.
Copy that same binding for C-a for term-line-mode, so that it does the same thing in both modes:
(define-key term-mode-map (kbd "C-a") 'term-send-raw)
Create a new binding which does the same thing. e.g.:
(define-key term-mode-map (kbd "s-a") (lambda () (interactive) (term-send-raw-string (string 1))))
n.b. Using (string 1) because C-a is ascii value 1. See the definition of term-send-raw.
I've tried linum and nlinum. Both have dreadful performance on files with 100k+ lines.
$ for x in {1.100000}; do echo $x; done > 100k.txt
$ emacs -q 100k.txt
M-x load-library linum
M-x linum-mode
M-> ;; it's not too bad to go to end of file
M-< ;; now this completely locks up emacs
The same operation with editors like joe is instantaneous.
Is there any solution other than to turn off line numbers with big files (exactly the type of files that you want to navigate with line numbers - I have in mind locating error lines in concatenated Javascript files)?
Or just use a different editor?
I think you found a bug, and you may report (report-emacs-bug) it. As per Tyler comment, it may have been already solved.
Things that may help you in the meanwhile... line-number-mode, goto-line, narrow-to-region and this cheapo-number-my-lines-in-a-tmp-buffer trick:
(shell-command-on-region (point-min) (point-max)
(concat "grep -n ^ " buffer-file-name)
(get-buffer-create "*tmp-linum*") nil t)
As far as I know, both linum and its derivative nlinum number lines even if you don't see them. In the case of 100k+ lines, this can be slow if numbering an individual line takes more than a few tenths of a millisecond. For me, (Fedora 19, Emacs 24.3.1), there's no noticeable delay. Try line-num.el, which only numbers lines that are currently visible and see if it fixes the problem.
Add this to .emacs file.
(global-linum-mode 1)
Since Emacs 26 you should use [global-]display-line-numbers-mode instead.
For example:
(global-display-line-numbers-mode 1)
or:
(add-hook 'prog-mode-hook #'display-line-numbers-mode)
(Or toggle them manually via M-x.)
The line numbering for these is implemented as part of the redisplay in C code, and is therefore efficient and performs well even with extremely large buffers.
To customize this feature use:
M-x customize-group RET display-line-numbers
I started using ruby-electric-mode. I like it except that I am used to closing open brackets myself (the other pairing are still useful to me). How can I make emacs suppress additional brackets when I type in the closing brackets myself? I now am manually deleting the auto-magically inserted bracket every time.
Thanks in advance,
Raghu.
It sounds like what you want is for the } to either jump to the (already inserted) }, or to simply insert a } and delete the } that was inserted earlier by the electric mode.
This code should do what you want, the choice of what to do on } is toggled by the variable my-ruby-close-brace-goto-close.
;; assuming
;; (require 'ruby)
;; (require 'ruby-electric)
(defvar my-ruby-close-brace-goto-close t
"Non-nill indicates to move point to the next }, otherwise insert }
and delete the following }.")
(defun my-ruby-close-brace ()
"replacement for ruby-electric-brace for the close brace"
(interactive)
(let ((p (point)))
(if my-ruby-close-brace-goto-close
(unless (search-forward "}" nil t)
(message "No close brace found")
(insert "}"))
(insert "}")
(save-excursion (if (search-forward "}" nil t)
(delete-char -1))))))
(define-key ruby-mode-map "}" 'my-ruby-close-brace)
It is a “customizable” setting. Run M-x customize-variable (ESCx if you do not have a Meta key) and customize ruby-electric-expand-delimiters-list.
Uncheck “Everything” and check only the ones you want to be automatically inserted. Be sure to also “Save for Future Sessions”.
If you decide that you mostly like the automatic insertions but that there are some places where you want to turn it off for a single keystroke, then use C-q (Control-q) before an open paren/bracket/brace/quote to suppress the automatic insertion of the closing mark.
Ran into the same issue. The solution I found is to:
Use autopair, which does exactly what you want. Make sure you install it.
Enable ruby-electric-mode but only for | because the rest is already taken care of.
This leads to the following code in your .emacs file:
(use-package autopair
:config (autopair-global-mode)
)
(use-package ruby-electric-mode
:init
(setq ruby-electric-expand-delimiters-list (quote (124)))
)
(add-hook 'ruby-mode-hook 'ruby-electric-mode)
This code uses use-package package, make sure you installed it (M-X list-packages, then find use-package, then i on the line, then x and restart emacs).
Also, that might interest people visiting this thread. I added this code to skip closing delimiters with TAB, it helps jumping over them. Comment out the while lines (and adjust )) to have a single TAB jump over all closing delimiters (taken from emacs board discussion):
(use-package bind-key)
(defun special-tab ()
"Wrapper for tab key invocation.
If point is just before a close delimiter, skip forward until
there is no closed delimiter in front of point. Otherwise, invoke
normal tab command for current mode.
Must be bound to <tab> using bind-key* macro from bind-key package.
Note, this function will not be called if `override-global-mode' is
turned off."
(interactive)
(defun next-char-delims (delims)
(let ((char (and (not (equal (point) (point-max)))
(string (char-after (point))))))
(when char (member char delims))))
(let ((open '("'" "\"" ")" "]" "}" "|")))
(if (next-char-delims open)
(progn (forward-char 1))
;;(while (next-char-delims open)
;; (forward-char 1)))
(call-interactively (key-binding (kbd "TAB"))))))
(if (macrop 'bind-key*)
(bind-key* (kbd "<tab>") 'special-tab)
(user-error "Must have bind-key from use-package.el to use special-tab function"))
This time, you need the bind-key package for this snippet to work.