我想知道人们通常如何浏览Linux环境中包含多个源文件的大型项目。我主要使用C和python,有时使用C ++,C#和Java。
我想知道特定的编辑器,插件等。我曾经在Windows上编程,所以像vi和emacs这样的编辑器并不属于我的联盟,但如果你认为这对我学习其中一个编辑器真的很有帮助请通过这些程序管理大型项目,并建议您使用任何特定的插件,以简化您的生活。
以下是几个场景:假设我正在处理文件F中的特定函数A,突然之间我意识到这个函数需要调用文件G中的函数B.我很快就需要导航到用于确定功能参数之类的功能,快速查看功能等。另一种情况是在文件中同时处理两个不同的位置并在这两个位置之间快速切换。
我正在使用eclipse来管理我的项目并进行开发(eclipse的自动完成非常缓慢)以及单独编辑文件,但似乎我无法真正达到这种效率水平。
请分享您的代码管理和导航技巧。
谢谢,
编辑:语言
答案 0 :(得分:7)
Emacs with etags - 参见例如EmacsWiki on Tags - 因为Emacs的默认模式适用于我关心的所有语言:R,C ++,C,shell,Perl,Python,SQL,......也可能你追求的是谁。 Exuberant Ctags将此概括为更多语言和编辑,包括vi系列。
答案 1 :(得分:5)
对于 vim爱好者(和我一样):vim + ctags做得很好。 grep也是你最好的朋友。
答案 2 :(得分:2)
嗯,你在谈论什么样的代码? C ++ / java / php / ruby / python我强烈推荐netbeans,特别是最新的dev版本, KDevelop for kde 4.2(来自svn)非常好,php / C#支持非常实验性但是如果你不介意随机崩溃它真的很好。 如果你不介意安装java来运行它,Netbeans是迄今为止Linux上最稳定的php / java / c ++ IDE。
答案 3 :(得分:1)
答案 4 :(得分:0)
您可以将MonoDevelop用于c ++。这将与您使用Windows / VS.Net时的体验非常相似。
答案 5 :(得分:0)
我是IntelliJ的粉丝。它的口号说明了一切:“愉快地发展”。当然,这假设您使用的是Java。虽然它确实支持包括Python在内的其他几种语言的插件。
答案 6 :(得分:0)
当我需要了解其他人的代码时,我经常使用Doxygen。我在编写自己的代码时使用了Vim和CTags。
答案 7 :(得分:0)
看看Kscope。它提供了一个右键菜单,为您提供了用C语言编写的任何源文件集的定义,引用,调用函数,调用函数等。在大项目中使用时,它是可靠且快速的。
我将它用于源导航,但对于编辑部分,我对geany感觉更舒服。它不仅限于C,并提供了良好的自动完成功能,可在您键入时提供函数的原型。仍然有一些粗糙的边缘,但Kscope + Geany组合是我现在最喜欢的组合,当谈到写作C.
答案 8 :(得分:0)
我使用Eclipse并大量使用搜索功能(对于C主要是文本搜索)。
我还启用了工具提示,可以显示文档或函数的开头。
标记出现也有助于在文件中查找内容。
我通常标记我使用TODO评论的地方。这些在侧栏中可见,因此在那里导航相对容易。
我还启用行号,与错误消息等相关联。
我认为在Eclipse中的两个不同窗口中编辑同一个文件是不可能的(但我很乐意被证明是错误的)。
答案 9 :(得分:0)
我正在使用gvim(Vim的GUI版本)进行大多数Perl和C / C ++编程。对于导航,我找到NERDTree,ctags,ack以及可能用Perl或其他任何东西编写的一些自定义脚本。我已将my Vim/gvim configuration放在我的网站上。正如人们可以看到的那样,我有“如此$ VIMRUNTIME / mswin.vim”,这使得Vim更加类似于Windows编辑器,并且更加熟悉来自它的人。许多硬核vim专家不建议使用它,但我仍然这样做。
Vim's homepage还有许多其他插件可能会有用。
答案 10 :(得分:0)
我使用了许多列出的项目:doxygen,etags等。但是,在大多数情况下,我发现从emacs运行良好的find-grep运行可以非常有效地搜索大型代码库。仍在努力设置CEDET和sematic。
这是我为特定源代码树编写的一些lisp代码,以及我的.emacs中这些函数的映射。代码构建了一个大的find-grep命令,该命令从我正在使用的源代码树的根开始。它遍历文件系统,寻找一些指示源树顶部的文件(在我的情况下为makefile)。我调整它直到它可以在几秒钟内完成搜索(我实际上编写了一个python脚本来帮助我识别大型二进制文件类型,这些类型会减慢我的搜索速度。)
(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)
)
)
答案 11 :(得分:-1)