How do I highlight CVS changes in Emacs? - emacs

I'm using emacs with cvs and have cvs mode enabled. I'd like to get line-by-line highlighting of changes from the latest version in CVS. I've seen this done in intellij where there is a green indication for lines added and another indication for lines modified and a third symbol for lines deleted.
Is there a cvs highlighting mode for emacs to show changes from the latest version of cvs? I'm not looking for a cvs diff type functionality that would open in a new buffer, but something that would indicate in my current buffer what lines have been modified.
In the following image there is a blue rectangle on the left side in what Intellij calls the "gutter" to indicate that the code is different than what is in source control.
(source: jetbrains.com)
I'm looking for similar functionality in emacs.

You can now check out diff-hl, which provides highlighting on the left window fringe.
So far I've tested it only on a few modern DVCSes, but if you're still using CVS, and it doesn't work as well, please file an issue.

Here's another answer that doesn't do what you want either, but may be useful.
C-x v g
runs the command vc-annotate.
That'll pop up a new buffer (I know, you didn't want one), but it'll have all the lines marked with who touched them when. And, bonus, they're color coded with a heatmap (red is most recent, blue is least), for easy identification of recent changes.
Of course the built-in version of vc-annotate doesn't scroll the buffer appropriately, so you'll want this advice:
(defadvice vc-annotate (around vc-annotate-and-scroll)
"scroll buffer to view current line in the annotated buffer"
(let ((pos (count-lines (point-min) (point))))
ad-do-it
(let ((orig-window (selected-window))
(window (other-window-for-scrolling)))
(select-window window)
(goto-line pos)
(select-window orig-window))))
(ad-activate 'vc-annotate)

You want vc-diff, which is on C-x v = by default. This gives you raw diff output in a temp buffer. The buffer uses diff-mode, which has a few neat tricks ... for example, you can use C-c C-e to apply the diff as a patch to another file. Use describe-mode (C-h m by default) in the diff buffer to find the other tricks.

Perhaps you'd like Ediff, which appears to do exactly what you want.

Related

in Emacs, how to enable automatic hiding of dired details?

I use a library called dired-details and dired-details+ to simplify dired's display, such that a line like this:
-rw-r--r--# 1 peter staff 22571 Apr 15 16:05 foo.txt
displays like this:
foo.txt
However, I have another function, which places all directories at the top of the list:
(defun mydired-sort ()
"Sort dired listings with directories first."
(save-excursion
(let (buffer-read-only)
(forward-line 2) ;; beyond dir. header
(sort-regexp-fields t "^.*$" "[ ]*." (point) (point-max)))
(set-buffer-modified-p nil)))
(defadvice dired-readin
(after dired-after-updating-hook first () activate)
"Sort dired listings with directories first before adding marks."
(mydired-sort))
and this second function interferes with dired-details, such that when I C-x d to open a dired buffer, the initial display shows the full extraneous details. Only by pressing g to revert-buffer to refresh the display do the directory details become hidden.
How do I enable hiding of dired details by default in all dired displays?
First, if you use Emacs 24.4 or later (or a developement version past 24.3), then you no longer need either dired-details.el or dired-details+.el. Starting with Emacs 24.4, Dired listing details are hidden by default. dired-hide-details-mode is the relevant mode.
If you use dired+.el (Dired+) then you can more easily take advantage of this new behavior -- it gives you all of the features offered by dired-details+.el. Use ( anytime to toggle this hiding. You can use Dired+ option
diredp-hide-details-initially-flag to change the default/initial state. See also option diredp-hide-details-propagate-flag.
If you use an Emacs version that is prior to Emacs 24.4 (so you need dired-details[+].el) then try loading dired-details+.el (which will load dired-details.el) after you have evaluated your code above. If that does not help, then try also adding this to your defadvice body, just after (mydired-sort): (dired-details-hide). If that does not work then we will need to look a bit further.
If you can upgrade your Emacs version then you will soon be able to use Emacs 24.4 (it is in pretest now), in which case you should be able to just load dired+.el and set option diredp-hide-details-initially-flag to non-nil.
Wrt sorting directories first: Are you on MS Windows? If so, consider using libraries dired-sort-menu.el and dired-sort-menu+.el. It lets you do that and much more.
UPDATE
The problem is that dired-details caches the list of overlays it uses to hide details. It has already done its job (because of dired-after-readin-hook), before your sorting is done, and that changes the buffer without updating the cache info. This will fix the problem (there is probably a more elegant way, but this will do):
(defadvice dired-readin
(after dired-after-updating-hook first () activate)
"Sort dired listings with directories first before adding marks."
(mydired-sort)
(let ((dired-details-internal-overlay-list ())) (dired-details-hide)))

How can I diff a single file with magit?

Say I've made a number of unrelated changes to uncoupled files in my git repo. I want to review and commit each of the files separately.
I run magit-status, and get a list of changed files. But the only magit diff commands I can find (d and D) diff entire revisons, not individual files.
I want the output of git diff <filename>, but in the magit diff buffer. How can I get magit to diff only one file?
Magit enables you to "review and commit each of the files separately" directly from the magit-status buffer, without the need for any separate diff buffers.
You just expand the file(s) you're interested in (with TAB, which shows you the diff for the file at point); then you can stage the bits of it that you want to commit (either the whole file, or individual hunks, or even a marked region) with s to stage (or u to unstage). Repeat for all the changes involved in that commit and, once everything necessary has been staged, press c to begin the commit.
You might prefer the visibility cycling behaviour you get by using C-TAB (repeatedly) instead of the simple toggle you get by default with TAB.
If you really do want to view the diff for a file in a separate buffer, you can do that from the file's buffer by calling magit-diff-buffer-file directly, or using the "diff" option (d) in magit-file-popup. e.g.:
(global-set-key (kbd "C-c m d") 'magit-diff-buffer-file)
(global-set-key (kbd "C-c m f") 'magit-file-popup)
Also note #assem's comment below:
You might also be interested in magit-ediff which is bound to e by default, and opens an ediff session for the diff/file at point.
Some other alternatives available in Emacs by default (i.e. not Magit) are:
C-xv= to call vc-diff
M-x vc-ediff for the ediff equivalent
M-x ediff-revision to create an ediff session with more options
I bind vc-ediff to C-xvC-= so that the two variants have similar key bindings.
I recommend watching the video by the creator of magit.
It's 20 min and it shows you the work-flow as it was intended.
Also, a small tip: you can use 1 2 3 to change
the diff verbosity of the current heading.
Another small tip: if you're not happy with the size of the hunks,
you can stage arbitrary regions by - that's right - marking a
region and pressing s. It's magic.
I didn't know about this option for a while, I was actually
dropping back to console and doing git add -p the old fashioned way.
There are definitely advantages to not going against the grain when using tools, as is exemplified by the other answers.
On the other hand, sometimes you just want to tell your editor what to do, and have people on the internet answer your questions instead of telling you want to do something else.
magit provides a menu interface for doing things to the current file through M-x magit-file-popup. The keys you need to press from here are "du". This may well be too many key presses for you, if this is the case you can call magit-diff directly like so:
(defun magit-diff-given-file (&optional file)
(interactive)
(unless file
(setf file buffer-file-name))
(magit-diff-working-tree "HEAD" nil (list (file-relative-name file (magit-toplevel file)))))
You might like to define your own function and keybinding for this.
magit-diff has advantages over vc-diff because if allows you to jump to the location of the diff.

clicking on emacs blows away x selection

Much of the time when I use the mouse to click on an emacs window, the x selection which I hope to paste into the buffer is blown away. This seems to be caused by the slight shift of the hand as I apply the left click causing an inadvertant "drag copy." I do not believe I will be able to break this particular habit.
One solution I have found to prevent this is to set:
(setq mouse-drag-copy-region nil)
however this has the unfortunate side effect of preventing me from using the mouse drag functionality at all in emacs. Is there a way to control mouse drag behavior so that a click is ignored unless it spands two or more characters within the buffer?
I am coding on Centos 5.x + GNOME 2 with GNU emacs 23.3.1 in case it makes a difference.
This appears to be a GTK/X issue; I can produce similar behavior with other apps.
The easiest solution to this is to modify the function mouse-drag-track, which can be found in mouse.el. To find the function definition, M-x find-function mouse-drag-track RET.
Copy that into your .emacs file and make one small change. Find the and statement that looks like:
(and mouse-drag-copy-region
do-mouse-drag-region-post-process
(let (deactivate-mark)
(copy-region-as-kill region-commencement
region-termination)))
And modify it to have the check to ensure the region is at least 2 characters. I've made this check to be 10 characters for easier testing:
(and mouse-drag-copy-region
(>= (abs (- region-commencement region-termination)) 10) ;; THIS IS NEW
do-mouse-drag-region-post-process
(let (deactivate-mark)
(copy-region-as-kill region-commencement
region-termination)))
I don't see a clean way to do this via advice or hooks or variable settings.
Be sure to have a (require 'mouse) before your definition of mouse-drag-track to ensure you override the built-in definition, as opposed to it overriding yours. You also might want to add a check to your .emacs right above the re-definition to remind you to check for new versions of the library/function you're overwriting:
(unless (eq emacs-major-version 23)
(error "check for new mouse-drag-track"))
This is a bug in emacs that was introduced into the source code history in 2001. I have posted a patch that can be applied to local installations. Hopefully the emacs maintainers will investigate further.
Here is my patch and discussion:
http://lists.gnu.org/archive/html/emacs-devel/2011-08/msg00818.html

How to remove directory window and add a cscope window in Emacs ECB?

Yesterday I installed ECB on my Emacs, and I find method window and history window quite useful. But directory tree window and source window less useful, if I can hide them I will save more space for method window and history.
Another problem is that I use cscope to search through the project for definitions and callers, the result of cscope is shown by splitting the main window into two. I'd like to know is it possible to make cscope result window fixed in ECB window, just like method window and history window?
Many thanks.
===============
Thanks to sanityinc and ecb documents, finally I create a layout with cscope fixed in it. I'll post code here in case it will help others.
(require 'ecb)
(ecb-layout-define "my-cscope-layout" left nil
(ecb-set-methods-buffer)
(ecb-split-ver 0.5 t)
(other-window 1)
(ecb-set-history-buffer)
(ecb-split-ver 0.25 t)
(other-window 1)
(ecb-set-cscope-buffer))
(defecb-window-dedicator ecb-set-cscope-buffer " *ECB cscope-buf*"
(switch-to-buffer "*cscope*"))
(setq ecb-layout-name "my-cscope-layout")
;; Disable buckets so that history buffer can display more entries
(setq ecb-history-make-buckets 'never)
There are a bunch of layout presets, listed here, one of which might work for you. Also, you can create a custom layout following the directions here, which can even be done interactively using the ecb-create-new-layout command.
The latter page also describes how to add a new fixed window, of the type you want for cscope.

Pin Emacs buffers to windows (for cscope)

For my day job, I live in Emacs. Utterly. I also have become pretty dependent on CScope to help me find things in the code.
Normally, I have 2 windows in a split (C-x 3):
alt text http://bitthicket.com/files/emacs-2split.JPG
And I use the right window for code buffers and the left window for the CScope search buffer. When you do a CScope search and select a result, it automatically updates the right-side window to show the buffer referred to by the result. This is all well and good, except that it causes me to lose my place in some other buffer that I was studying. Sometimes this is no biggie, because [C-s u] gets me back to where I was.
What would be better, though, is to have 3 split windows like this ([C-x 2] in the left window):
alt text http://bitthicket.com/files/emacs-3split.jpg
And have the bottom left window contain the CScope search buffer, and the top left window be the only buffer that CScope ever updates. That way, I can see my CScope searches and navigate around the code without losing the buffer I'm focused on.
Anyone know how I can do that?
Put this in your .emacs file:
;; Toggle window dedication
(defun toggle-window-dedicated ()
"Toggle whether the current active window is dedicated or not"
(interactive)
(message
(if (let (window (get-buffer-window (current-buffer)))
(set-window-dedicated-p window
(not (window-dedicated-p window))))
"Window '%s' is dedicated"
"Window '%s' is normal")
(current-buffer)))
Then bind it to some key - I use the Pause key:
(global-set-key [pause] 'toggle-window-dedicated)
And then use it to "dedicate" the window you want locked. then cscope can only open files from its result window in some OTHER window. Works a charm. I specifically use it for exactly this purpose - keeping one source file always on screen, while using cscope in a second buffer/window, and looking at cscope results in a third.
Well, I decided to not be a reputation-whore and find the answer myself. I looked in cscope.el as shown on the Emacs wiki, as well as the xcscope.el that comes with the cscope RPM package on RHEL.
Neither appear to give a way to do what I'm wanting. The way is probably to edit the ELisp by adding a package variable like *browse-buffer* or something and just initialize that variable if not already initialized the first time the user does [C-c C-s g] or whatever, and always have the resulting code shown in *browse-buffer*. Then the user can put the *browse-buffer* wherever he wants it.