a function that looks for "string" existing in a file path - emacs

I'm used to regex in Ruby, so i'm a lisp noob.
(global-set-key (kbd "C-c t")
(lambda()
(interactive)
(if string-match-p file-name-directory "spec"
(shell-command (concat "rspec " (file-name-directory (buffer-file-name))))
)
)
)
Basically i want to only run this line (or an else for 'test') if the file-name-directory has the word spec in it.
Example: /user/me/app/spec/test.rb
How does one get the if statement to work?
so far i get: Symbol's value as variable is void: string-match-p in the mini buffer. Thanks.

I assume you want this to act on the current buffer, if so, try this:
(global-set-key (kbd "C-c t")
(lambda()
(interactive)
(let* ((full-name (buffer-file-name))
(path (when full-name
(file-name-directory full-name))))
(when (and path (string-match "spec" path))
(shell-command (concat "rspec " path))))))

Related

emacs global-set-key M-, seems to be overridden and does not work after upgrading some packages in emacs

Here is my .emacs content. Can someone please help.
(global-set-key (kbd "M-,") 'pop-tag-mark)
(setq projecthome "/tmp/myproject")
(add-hook 'ess-mode-hook
(lambda ()
(let ((ess-build-tags-command "rtags('%s', recursive = TRUE, pattern = '\\\\.[RrSs](rw)?$',ofile = '%s')")
(my-tags-file (concat projecthome "/R/TAGS")))
(ess-build-tags-for-directory (concat projecthome "/R/") (concat projecthome "/R/TAGS"))
(sleep-for 5)
(visit-tags-table my-tags-file)
)))

Emacs; custom functions defined repetitively, how to use dolist, or other approach

Emacs' Bookmarks are great, as is navigating the list of buffers. But I find it nice to have shorter chords to get directly to where I want to go. So I have been accruing a repetitive set of functions and keybindings for all my favorite files and folders.
I wondered if I could use a dolist to handle this repetitiveness, but am no good programmer.
Here is one of the (seven and rising) repetitively defined functions, and a feeble attempt at writing the dolist following:
(defun jump-to-main ()
(interactive)
(find-file main))
(global-set-key (kbd "C-c m") 'jump-to-main)
This might barely qualify as pseudocode:
(dolist (x '(("m" main)
("t" tech))
(defun (concat 'jump-to- (cdr x)) ()
(interactive)
(find-file (cdr x)))
(global-set-key (kbd (concat "C-c " (car x)))
'(concat 'jump-to- (cdr x)))
))
The payoff in an elegant init file, versus how fast I am at solving at Lisp problems... hoping the Stackoverflow can save me.
Other strategies and approaches are appreciated.
EDIT:
With lawlist's suggestion, my question may reduce and be more clear presented the following way. I would like to reduce the repetition in the following series of keybindings.
(global-set-key (kbd "C-c A")
(lambda ()
(interactive)
(find-file fileA)))
(global-set-key (kbd "C-c B")
(lambda ()
(interactive)
(find-file fileB)))
...
(global-set-key (kbd "C-c Z")
(lambda ()
(interactive)
(find-file fileZ)))
fileK for example expands to something like "~/fileK.txt".
EDIT:
So here is another try:
(dolist (x '(("m" main)
("t" tech))
(global-set-key (kbd (concat "C-c " (car x)))
(lambda ()
(interactive)
(find-file (cdr x))
))))
The keybinding part seems okay, but (find-file (cdr x)) isn't doing what I need, and I couldn't fix it in a small amount of googling lisp.
Here are the expressions I'm using to focus on the broken parts:
(setq somefile "~/somefile.txt")
(setq x '("s" . somefile))
(concat "C-c " (car x))
(find-file (cdr x))
The last line is the one that doesn't work, as (cdr x) apparently evaluates to (main). I tried slipping in an eval to expand the main variable, but it doesn't seem...
Reading Phil's answer now, this may take me a while.
FWIW, a fairly direct translation of your pseudo-code is:
(defvar my-file-main (expand-file-name "~/main") "My main file")
(defvar my-file-tech (expand-file-name "~/tech") "My tech file")
(dolist (x '(("m" . my-file-main)
("t" . my-file-tech)))
(let* ((sym (cdr x))
(func (intern (concat "jump-to-" (symbol-name sym)))))
(defalias func `(lambda ()
,(format "Jump to file `%s'." (symbol-name sym))
(interactive)
(find-file ,sym)))
(global-set-key (kbd (concat "C-c " (car x))) func)))

Emacs: how to break out of ido minibuffer?

I'm generally using ido-switch-buffer, but sometimes when there are too many candidates,
helm-buffers-list is preferable. But it's a hassle to break out of ido,
call helm and re-enter the lost information.
So I wrote this code, that re-uses information entered in ido directly in helm:
(require 'helm-buffers)
(defun switch-to-helm-buffers-list ()
"Emulate `helm-buffers-list' call with ido contents as initial input."
(interactive)
(let ((str (minibuffer-contents-no-properties)))
(helm :sources '(helm-source-buffers-list
helm-source-ido-virtual-buffers
helm-source-buffer-not-found)
:buffer "*helm buffers*"
:keymap helm-buffer-map
:truncate-lines t
:input str)
;; (ido-exit-minibuffer)
))
(add-hook
'ido-setup-hook
(lambda()
(define-key ido-buffer-completion-map "\C-i"
'switch-to-helm-buffers-list)))
One problem is that ido is left to linger in the minibuffer.
When I add a call ido-exit-minibuffer before helm, it's not called.
And when I add it after, it resets the window configuration.
How can I solve this problem?
See answer https://stackoverflow.com/a/21165658/1937596
First, I patch your function a little.
(require 'helm-buffers)
(defun switch-to-helm-buffers-list ()
"Emulate `helm-buffers-list' call with ido contents as initial input."
(interactive)
(let ((str ido-text))
(helm :sources '(helm-source-buffers-list
helm-source-ido-virtual-buffers
helm-source-buffer-not-found)
:buffer "*helm buffers*"
:keymap helm-buffer-map
:truncate-lines t
:input str)
))
My recipe patches the body of function ido-buffer-internal (internal for ido-switch-buffer) too.
You have to execute this code once.
(eval
(read
(replace-regexp-in-string
"cond"
"cond ((eq ido-exit 'eab-ido-helm) (call-interactively 'switch-to-helm-buffers-list)) "
(save-window-excursion
(find-function-do-it 'ido-buffer-internal nil 'switch-to-buffer)
(let ((bgn (point)))
(forward-sexp)
(let ((end (point)))
(buffer-substring-no-properties bgn end)))))))
And I add one auxiliary function.
(defun eab/ido-helm ()
(interactive)
(setq ido-exit 'eab-ido-helm)
(exit-minibuffer))
Note, I use eab/ido-helm instead of switch-to-helm-buffers-list in define-key.
(add-hook
'ido-setup-hook
(lambda()
(define-key ido-buffer-completion-map "\C-i"
'eab/ido-helm)))
Here's what I've come up with. No patching required.
(define-key ido-buffer-completion-map "\C-i" 'ido-buffer-helm)
(defvar ibh-initial nil)
(defun ibh-hook ()
(when ibh-initial
(let ((str ibh-initial))
(setq ibh-initial)
(helm :sources '(helm-source-buffers-list
helm-source-ido-virtual-buffers
helm-source-buffer-not-found)
:buffer "*helm buffers*"
:keymap helm-buffer-map
:truncate-lines t
:input str)))
(remove-hook 'post-command-hook 'ibh-hook))
(require 'delsel)
(defun ido-buffer-helm ()
(interactive)
(setq ibh-initial ido-text)
(add-hook 'post-command-hook 'ibh-hook)
(minibuffer-keyboard-quit))

define-key: Symbol's function definition is void: lisp-interaction-mode-map

I've got a snippet I want to bind to a key:
(define-key (lisp-interaction-mode-map) (kdb "C-c e")
(let ((result (eval (read (buffer-substring
(point-at-bol) (point-at-eol))))))
(goto-char (point-at-eol))
(insert (format " ; %s" result))))
however, when C-c v that in *scratch*, I get
define-key: Symbol's function definition is void: lisp-interaction-mode-map
You have parentheses around lisp-interaction-mode-map, which Lisp interprets to mean that you want to call the function named lisp-interaction-mode-map. Instead, you want to use it as variable.
I also did some other edits you'll need to get what you have to work. I assumed you wrote read in order to prompt for a user-inputted string:
(define-key lisp-interaction-mode-map (kbd "C-c C-e")
(lambda (result)
(interactive (list (read-from-minibuffer (buffer-substring (point-at-bol) (point-at-eol)))))
(goto-char (point-at-eol))
(insert (format " ; %s" result))))
What's wrong with the normal form?
(define-key lisp-interaction-mode-map [(control e)] 'eval-defun)

How to I remap the Emacs command M-d into the macro M-b, M-d?

I would like the "delete to end of word" command to delete the word, regardless of cursor position.
(defun my-kill-word ()
(interactive)
(backward-word)
(kill-word 1))
(global-set-key (kbd "M-d") 'my-kill-word)
A better code could be:
(defun my-kill-word ()
(interactive)
(unless (looking-at "\\<")
(backward-word))
(kill-word 1))
(global-set-key (kbd "M-d") 'my-kill-word)
So we move backward only if we are not at the beginning of the word
yet.