This will be amassed post in the vein of this one. I amassed enough changes to my already blogged-about improvements to emacs to go over what I changed. When possible, I’ll link to previous blog posts about them; In some cases I have just minor additions that aren’t big enough to go in their own post.
Hooks are quite nice, but they have some problems with lambda functions. Lambdas in hooks cannot be removed easily or modified; you’ll have to modify the hook variable manually in order to remove or modify that function. After having to play around with many of my hooks, I got tired of setting hook variables to nil and re-adding everything so I changed many of my hooks that used lambdas to instead be defined as regular functions. A list of some of these is below:
(defun turn-on-visual-line-mode () (interactive) (visual-line-mode 1)) (add-hook 'text-mode-hook 'turn-on-visual-line-mode) (defun c-mode-common-hook-fn () (interactive) (c-toggle-syntactic-indentation 1) (setq c-basic-offset 4) (c-toggle-hungry-state 1) (c-toggle-electric-state 1) (flymake-mode 1)) (add-hook 'c-mode-common-hook 'c-mode-common-hook-fn) (add-hook 'c-mode-common-hook 'yas/minor-mode-on) (add-hook 'c-mode-hook 'c-turn-on-eldoc-mode)
I also started interpreters for most of the languages I have customizations for, so I decided that Python should be no exception. The following code snippet will open a python interpreter as a new buffer.
(python-switch-to-python t)
I also made yet another change to ido-goto-symbol. This function will prompt the user, using ido, for a function in the current file to move to and will then move point to the definition of the function. I updated it so that if the point is on a function name, that name will appear first in the list of options (and thus be the default choice).
(defun ido-goto-symbol () "Will update the imenu index and then use ido to select a symbol to navigate to" (interactive) (imenu--make-index-alist) (let ((name-and-pos '()) (symbol-names '())) (flet ((addsymbols (symbol-list) (when (listp symbol-list) (dolist (symbol symbol-list) (let ((name nil) (position nil)) (cond ((and (listp symbol) (imenu--subalist-p symbol)) (addsymbols symbol)) ((listp symbol) (setq name (car symbol)) (setq position (cdr symbol))) ((stringp symbol) (setq name symbol) (setq position (get-text-property 1 'org-imenu-marker symbol)))) (unless (or (null position) (null name)) (add-to-list 'symbol-names name) (add-to-list 'name-and-pos (cons name position)))))))) (addsymbols imenu--index-alist) (let* ((symbol-at-point (symbol-name (symbol-at-point))) (selected-symbol (ido-completing-read "Symbol? " (if (member symbol-at-point symbol-names) (cons symbol-at-point (remove-if (lambda (x) (string-equal x symbol-at-point)) symbol-names)) symbol-names))) (position (cdr (assoc selected-symbol name-and-pos)))) (if (markerp position) (goto-char position) (goto-char (overlay-start position)))))))
I talked about my methods to update dired here. In the comments was a suggestion to just use auto-revert-mode. This greatly simplifies the code for this functionality, and solves some of the issues I mentioned in that post, so I now use it instead for dired buffers.
(defun turn-on-auto-revert-mode () (interactive) (auto-revert-mode 1)) (add-hook 'dired-mode-hook 'turn-on-auto-revert-mode)
ff-find-other-file will go to a ‘matching’ file in a C or C++ buffer. If on a #include line, it will open the file being included; otherwise, if you are in a header file it will go to the corresponding implementation file and go to the corresponding header if you are in an implementation file. This is quite useful, so it now has it’s own keybinding.
(define-key c-mode-base-map (kbd "C-c o") 'ff-find-other-file)
I ended up changing the implementation of my auto-indentation functions. I moved the list of major-modes that this would be active in to a new list which both yank and yank-pop check. Also in the comments of that post was a suggestion to advise kill-line instead of replacing it, and the advice works quite well so I am now using it.
(defvar programming-major-modes '(emacs-lisp-mode scheme-mode lisp-mode c-mode c++-mode objc-mode latex-mode plain-tex-mode java-mode) "List of programming modes") (defadvice yank (after indent-region activate) (if (member major-mode programming-major-modes) (let ((mark-even-if-inactive t)) (indent-region (region-beginning) (region-end) nil)))) (defadvice yank-pop (after indent-region activate) (if (member major-mode programming-major-modes) (let ((mark-even-if-inactive transient-mark-mode)) (indent-region (region-beginning) (region-end) nil)))) (defadvice kill-line (after fixup-whitespace activate) "Call fixup-whitespace after killing line." (save-excursion (if (looking-back "^\s*") (funcall indent-line-function) (fixup-whitespace))))
I also added a few new keybindings. I recompile frequently, so a keybinding for it seems appropriate. So does shortening the keybinding for goto-line.
(global-set-key (kbd "<f2>") 'recompile) (global-set-key (kbd "M-g") 'goto-line)
The last improvement I have is yet another change to imenu-java-generic-expression. I’m still waiting for the FSF to get my copyright assingment forms so that this becomes a part of emacs proper, but until then I updated the regexp to work with functions that throw Exceptions as well.
(defun set-java-generic-expression () (setq imenu-generic-expression `((nil ,(concat "[" c-alpha "_][\]\[." c-alnum "_<> ]+[ \t\n\r]+" ; type spec "\\([" c-alpha "_][" c-alnum "_]*\\)" ; method name "[ \t\n\r]*" ;; An argument list htat is either empty or contains any number ;; of arguments. An argument is any number of annotations ;; followed by a type spec followed by a word. A word is an ;; identifier. A type spec is an identifier, possibly followed ;; by < typespec > possibly followed by []. (concat "(" "\\(" "[ \t\n\r^M]*" "\\(" "@" "[" c-alpha "_]" "[" c-alnum "._]""*" "[ \t\n\r^M]+" "\\)*" "\\(" "[" c-alpha "_]" "[\]\[" c-alnum "_.]*" "\\(" "<" "[ \t\n\r^M]*" "[\]\[.," c-alnum "_<> \t\n\r^M]*" ">" "\\)?" "\\(\\[\\]\\)?" "[ \t\n\r^M]+" "\\)" "[" c-alpha "_]" "[" c-alnum "_]*" "[ \t\n\r^M,]*" "\\)*" ")" "[.," c-alnum " \t\n\r^M]*" "{" )) 1)))) (add-hook 'java-mode-hook 'set-java-generic-expression)
That’s all for today - if you have any additional remarks, let me know in the comments.