10

I was wondering how people usually navigate through large projects with several source files in Linux environment. I primarily work with C and python and sometimes with C++, C# and Java.

I wanted to know specific editors, plugins etc. I used to program on windows so editors like vi and emacs are not really in my league, but if you think if it could be really helpful for me to learn one of these editors please suggest so and any specific plug-ins you use to make your life simpler with managing large projects with these programs.

Here are a couple of scenarios: Let's say I am working on a particular function A in file F, and all of a sudden I realize that this function needs to call function B in file G. I quickly need to navigate to that function to determine things like function parameters, take a quick look at the function etc. Another scenario would be working on two different locations at one time in a file and switching quickly between these two locations.

I am using eclipse to manage my project and do development (eclipse's auto completion is painfully slow) and geany to edit files individually, but seems like I can't really get to that level of efficiency.

Please share your code management and navigation techniques.

Thanks,

edit: languages

verma
  • 1,285
  • 1
  • 13
  • 19

12 Answers12

7

Emacs with etags -- see eg EmacsWiki on Tags -- as Emacs' default modes work for all languages I care about: R, C++, C, shell, Perl, Python, SQL, ... and probably also the ones you are after. The Exuberant Ctags generalise this to more languages and editors, including the vi family.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • I will give emacs a shot. I will try to spend some time with it today and see where it takes me. – verma Aug 03 '09 at 15:31
  • I gave emacs another try, it's working well for me so far. The good thing is that its regarding most of the keystrokes I use when I edit files in other GUI based editors (like Visual Studio, Eclispe etc.). I totally love how well it indents my C code. I am going to mark your response as the answer. Thanks! – verma Aug 05 '09 at 23:34
5

For vim lovers (like me): vim + ctags does great job. Also grep is your best friend.

Artyom
  • 31,019
  • 21
  • 127
  • 215
  • 1
    To clarify for the OP, who seems reluctant to learn vim: navigating to the function if the cursor is on that functions name is: [ If you want to go to the function foo and the cursor is not on the name 'foo': :ta foo Each jump is recorded on a stack, and navigating back through the stack is: t Advice to the OP: you do want to learn vim and/or emacs. Spend enough time to be moderately proficient with both, then select one and learn it well. – William Pursell Aug 03 '09 at 12:19
  • Thanks for the advice, I do want to learn one of these editors. Its just that starting up with these is such a hassle while I can go ahead and use a simpler editor which gets the job done. I am sure they would be great in the long run, just starting up is a pain. I will give them a shot though, I would say I know 10% of vi, but emacs is a whole new world for me. – verma Aug 03 '09 at 15:28
2

Well, what kinda code are you talking about? C++/java/php/ruby/python I highly recommend netbeans, specially the latest dev builds, also KDevelop for kde 4.2 (from svn) is really nice, the php/C# support is very experimental but if you don't mind the random crash its really good. Netbeans is by far the most stable IDE for php/java/c++ on linux if you don't mind installing java to run it.

OneOfOne
  • 95,033
  • 20
  • 184
  • 185
  • sounds good, I will take a look. I primarily work with C and python. Occasionally with C++, C# and Java. – verma Aug 03 '09 at 02:27
  • netbeans have python support, and should be somewhat easy to use it for c instead of c++. – OneOfOne Aug 03 '09 at 02:57
  • netbeans is great, but it just didn't cut it. I don't know why but it looked awfully ugly (I am on Arch Linux x86_64 running Gnome). I couldn't configure it to use Monospace 10 as the editor font. Also the menus and all were drawn really badly, no borders or anything. – verma Aug 05 '09 at 23:40
  • thats weird, what version of the java jdk? try to start it with --laf GTK – OneOfOne Aug 06 '09 at 00:54
1

For grepping in files, ack is better than actual grep.

For navigating between files, bash alias that runs kwrite on background together with bash completion for file names is enough for me.

che
  • 12,097
  • 7
  • 42
  • 71
0

You can use MonoDevelop for c++. It will be a very similar experience as you've had with Windows / VS.Net.

xanadont
  • 7,493
  • 6
  • 36
  • 49
0

I'm a big fan of IntelliJ. Its slogan says it all: "Develop with pleasure". Of course, this assumes you are using Java. Although it does have supported plugins for several other languages including Python.

joeslice
  • 3,454
  • 1
  • 19
  • 24
0

I often use Doxygen when I need to understand code from someone else. I use Vim with CTags while writing my own code.

Neil
  • 2,378
  • 1
  • 20
  • 28
0

Take a look at Kscope. It provides a right click menu to give you the definitions, references, calling function, called functions etc... for any set of source files written in C. It is reliable and fast when used on big project.

I use it for source navigation, but for the editing part, I feel more comfortable with geany. It is not limited to C, and provides a good auto-completion feature, that will provide the prototype of a function as you type it. Still has some rough edges, but the Kscope + Geany combo is my favourite combo for now, when it comes to writing C.

shodanex
  • 14,975
  • 11
  • 57
  • 91
0

I use Eclipse and make heavy use of the search function (for C mostly text search).

I also have tooltips enabled, which can show the documentation or beginning of a function.

Mark occurrences is also helpful to find stuff within a file.

I typically mark places where I work with TODO comments. These are visible in the sidebar, so it is relatively easy to navigate there.

I also enable line numbers, for correlating with error messages and such.

I don't think it is possible to edit the same file in two different windows in Eclipse (but I would be happy to be proven wrong).

starblue
  • 55,348
  • 14
  • 97
  • 151
  • Text search is slow in a big database; and isn't syntax-specific, e.g. I might want to find [only] the places where a class' constructor is invoked, not every other place where the class' name is mentioned. – ChrisW Jan 17 '11 at 02:19
  • Yes, but I don't think you can do better for C and C++ with Eclipse CDT. CDT is not that good, often the semantic search doesn't find all occurrences. So I'd rather have a slow search that finds too much than a fast search that may miss occurrences. For Java it is different, the JDT understands the semantics of Java much better. – starblue Jan 17 '11 at 15:34
0

I'm using gvim (Vim's GUI version) for most Perl and C/C++ programming. For navigation I find NERDTree, ctags, ack and possibly some custom scripts written in Perl or whatever. I have placed my Vim/gvim configuration on my site. As one can see there, I have "so $VIMRUNTIME/mswin.vim" there which makes Vim much more similar to Windows editor, and more familiar to people coming from it. Many hard-core vim experts don't recommend using it, but I still do.

There are many other plugins over at Vim's homepage which may prove useful.

Shlomi Fish
  • 4,380
  • 3
  • 23
  • 27
0

I use many of the items listed: doxygen, etags, etc. However, in most cases I've found a well tuned find-grep run from emacs can be very effective at searching large code bases. Still working on setting up CEDET and sematic.

Here's some lisp code I wrote for a particular source tree and the mappings to these functions in my .emacs. The code builds a large find-grep command which starts at the root of the source tree I'm working inside of. It traverses up the file system looking for some file which indicates the top of the source tree (makefile in my case). I tuned it until it could complete the search in a few seconds (I actually wrote a python script to help me identify large binary file types which were slowing my search down).

(global-set-key (quote[f3]) (quote set-fg-suffix))
(global-set-key (quote[f4]) (quote fg))

(defun mkpath (list)
  "Return a string which is the concatenation of the list."
  (let ( (result "") )
    (while list
      (setq result (concat result (car list)))
      (setq result (concat result "/"))
      (setq list (cdr list))
      )
    result ; Since this is the final evaluation, it's the returned from the function.
    )
  )

(defun find-best-root (anchor-file &optional empty-on-failure)
  "Examines the parent directories of the current buffer.  Looks for a parent that contains the
file passed in the anchor-file argument.  This is the directory I want."

  (if (not buffer-file-name)
      ;; Certain buffer (e.g., *scratch*) return nil from buffer-file-name.  In that case,
      ;; set the best path to "/" since that's the only path which can be counted on.
      (if (eq nil empty-on-failure)
          "/"
        ""
        )
    (let ((path-depth (safe-length (split-string (file-name-directory buffer-file-name) "/" 1)))
          (best-root (if (eq nil empty-on-failure)
                         (file-name-directory buffer-file-name)
                       ""))
          (exclude-from-path 1))
      (while (<= exclude-from-path (+ path-depth 1))
        (setq path-as-list (butlast (split-string (file-name-directory buffer-file-name) "/") exclude-from-path))
        (setq potential-root (mkpath path-as-list))
        (message (concat "Checking in " potential-root))
        (if (file-exists-p (concat potential-root anchor-file))
            (progn (setq best-root potential-root)
                   (setq exclude-from-path (+ path-depth 2)) ;; Break from the loop.
                   (message (concat "Found " anchor-file)))
          (setq exclude-from-path (+ exclude-from-path 1)))
        )
      best-root
      )
    )
  )

(if (eq system-type 'gnu/linux)
    (progn (setq marker-file "makefile")
           (setq find-filters (concat " -type d "
                                      "-path \"*/build\" -prune -o "
                                      "-path \"*/.git\" -prune -o "
                                      "-path \"*/ext\" -prune -o "
                                      "-path \"*/pycommon\" -prune -o "
                                      "\"(\" "
                                      "\! -iname \"BROWSE\" "
                                      "-and \! -iname \"FILES\" "
                                      "-and \! -iname \"TAGS\" "
                                      "-and \! -iname \"*.a\" "
                                      "-and \! -iname \"*.bin\" "
                                      "-and \! -iname \"*.cs\" "
                                      "-and \! -iname \"*.css\" "
                                      "-and \! -iname \"*.d\" "
                                      "-and \! -iname \"*.dat\" "
                                      "-and \! -iname \"*.html\" "
                                      "-and \! -iname \"*.ico\" "
                                      "-and \! -iname \"*.jar\" "
                                      "-and \! -iname \"*.json\"  "
                                      "-and \! -iname \"*.o\" "
                                      "-and \! -iname \"*.pdf\" "
                                      "-and \! -iname \"*.php\" "
                                      "-and \! -iname \"*.png\" "
                                      "-and \! -iname \"*.pyc\" "
                                      "-and \! -iname \"*.so\" "
                                      "-and \! -iname \"*.sql\" "
                                      "-and \! -iname \"*.txt\" "
                                      "-and \! -iname \"*.xml\" "
                                      "\")\" "
                                      "-print0 | xargs -0 grep -nHi -e "))
           ))

(setq custom-find-grep-path-suffix "")
(defun set-fg-suffix (suffix)
  "Set an optional suffix for the search.  This is useful for more fine grained searching."
  (interactive "sEnter Search Suffix: ")
  (if (string= "" suffix)
      (message "The optional search suffix is now empty.")
    (message (concat "The optional search suffix is now '" suffix "'."))
    )
  (setq custom-find-grep-path-suffix suffix)
)


(defun fg ()
  "A custom find grep that dynamically sets the search path based on the buffer.
Regular Expression Examples:
-E \"struct.*hash\"  When using special characters, enclose regexp in quotes.
-E \"^text$\"        ^ Matches beginning of line,  $ matches end of line.
-E \"main\\(.*\\)\"  .* Matches everything, parenthesis require escaping."
  (interactive)
  (let ((fg-tt-filters find-filters ))
    (setq my-find-grep-command "find \"")
    (setq my-find-grep-command (concat my-find-grep-command (find-best-root marker-file)))
    (setq my-find-grep-command (concat my-find-grep-command custom-find-grep-path-suffix))
    (setq my-find-grep-command (concat my-find-grep-command "\""))
    (setq my-find-grep-command (concat my-find-grep-command fg-tt-filters))
    (grep-apply-setting 'grep-find-command my-find-grep-command)
    (call-interactively 'find-grep)
  )
)
Tom Weiss
  • 797
  • 1
  • 8
  • 15
-1

Spacemacs integrated with projectile is a nice choice.

One can search a project files using utilities such as ack, grp, ag.

(ag is better than ack or grep)

user3113626
  • 649
  • 8
  • 17
  • On its own, this answer appears to be an uninformed opinion. Please improve it by explaining _why_ it is a nice choice. What features are particularly useful? How does it compare with other answers? Are there any negatives to be aware of? – Toby Speight Mar 15 '16 at 13:08