emacs + comint-dynamic-complete-filename after '=' - bash

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)

Related

inf-ruby eval current line

inf-ruby supports ruby-send-region, which combined with marker-fu can evaluate a single line, but I'd prefer to have a function like ruby-send-line to eval the cursor's current line in one keystroke. Does this exist? If not, how can I begin to make it?
The following appears to work reasonably well:
(defun ruby-send-line ()
"Send the current line to the inferior Ruby process."
(interactive)
(ruby-send-region (point-at-bol) (point-at-eol)))

Emacs: How to enable highlighting breakpoints in a text terminal (emacs -nw)

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.

How can I specify the package name when launching a Lisp program from the command line?

I'm calling a Lisp function (and a few other thing) from a shell script. For brevity, below is relevant part of the script :
./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(format T "~a"
(CC3::sunset (CC3::fixed-from-gregorian (CC3::gregorian-date 1996
CC3::february 25)) CC3::jerusalem))'
728714.7349874675
The above code works fine but I had to append the package name CC3 for every symbol that is used; which makes the code unwieldy and hard to type.
I tried to simplify it like so, using use-package :
./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(format T "~a"
(use-package "CC3") (sunset (fixed-from-gregorian (gregorian-date 1996 february 25)) jerusalem))'
Much easier to read and type, but unfortunately it doesn't work. I've tried all sorts of ways to include the use-package directive but so far no success.
Is it even possible to include a use-package directive while launching a Lisp program via the GNU Common Lisp's (gcl) load directive?
Update:
The solution is to use multiple evals as suggested by the accepted answer.
./gcl -load /tmp/calendrica-3.0.cl -batch -eval
'(use-package "CC3")' -eval '(format T "~a" (sunset
(fixed-from-gregorian (gregorian-date 1996 february 25)) jerusalem))'
Maybe you could use multiple eval, here is what I do with sbcl.
#!/bin/sh
sbcl --noinform \
--eval '(load "boot.lisp")' \
--eval '(in-package #:my-pkg)' \
--eval "(do-something-useful)" # do-something-useful is in my-pkg
It's maybe possible to do that but it will be ugly.
If you give it a form form evaluation, it will read the form first. Thus it then is too late during evaluation to change the reader (telling new packages, ...). Thus it needs to be done before.
CL-USER 1 > (eval (read-from-string "(foo::bar)"))
Error: Reader cannot find package FOO.
Better:
CL-USER 5 > (eval '(progn (defpackage foo (:use "CL"))
(read-from-string "(foo::bar)")))
(FOO::BAR)
So, if you want to pass a single form to eval, you would write which first creates the package and then reads/evals from a string, which is encoded in the form. Tricky.
Alternatives:
maybe the Lisp allows at startup multiple -eval forms? Do whatever you need to initialize Lisp to know about the packages in the first -eval form. Then have the code to execute in the second form.
write a file and put the necessary forms there. Load it. Since a file can contain multiple forms, you can have DEFPACKAGE, IN-PACKAGE or similar on top and then have the rest of the code in the file depending on it.

Use z (jump around) in Emacs to find directories

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.

Emacs line numbering performance

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

Resources