10

我想知道人们通常如何在 Linux 环境中浏览具有多个源文件的大型项目。我主要使用 C 和 python,有时使用 C++、C# 和 Java。

我想知道特定的编辑器、插件等。我以前在 Windows 上编程,所以 vi 和 emacs 等编辑器并不真正适合我,但如果你认为学习这些编辑器中的一个对我是否真的有帮助,请建议以及您使用的任何特定插件,通过这些程序管理大型项目,让您的生活变得更简单。

这里有几个场景:假设我正在处理文件 F 中的特定函数 A,突然间我意识到这个函数需要调用文件 G 中的函数 B。我需要快速导航到该函数以确定诸如函数参数,快速查看函数等。另一种情况是同时在文件中的两个不同位置上工作,并在这两个位置之间快速切换。

我正在使用 eclipse 来管理我的项目并进行开发(eclipse 的自动完成速度非常慢)并且 geany 可以单独编辑文件,但似乎我无法真正达到那种效率水平。

请分享您的代码管理和导航技术。

谢谢,

编辑:语言

4

12 回答 12

7

带有 etags 的 Emacs —— 参见标签上的 EmacsWiki —— 因为 Emacs 的默认模式适用于我关心的所有语言:R、C++、C、shell、Perl、Python、SQL ……也许还有你所追求的语言. Exuberant Ctags将此推广到更多的语言和编辑器,包括 vi 家族。

于 2009-08-03T02:24:40.373 回答
5

对于vim 爱好者(比如我):vim + ctags 做得很好。grep 也是你最好的朋友。

于 2009-08-03T07:44:56.850 回答
2

好吧,你在说什么代码?C++/java/php/ruby/python 我强烈推荐 netbeans,特别是最新的开发版本,kde 4.2(来自 svn)的 KDevelop 非常好,php/C# 支持非常实验性,但如果你不介意随机崩溃它真的很好。如果您不介意安装 java 来运行它,Netbeans 是迄今为止 Linux 上 php/java/c++ 最稳定的 IDE。

于 2009-08-03T02:24:26.677 回答
1

对于文件中的 grep,ack比实际的 grep 更好。

对于文件之间的导航,在后台运行kwrite的 bash 别名以及文件名的 bash 补全对我来说就足够了。

于 2009-08-03T10:57:42.643 回答
0

您可以将 MonoDevelop 用于 c++。这将是您在 Windows / VS.Net 中获得的非常相似的体验。

于 2009-08-03T02:27:36.393 回答
0

我是IntelliJ的忠实粉丝。它的口号说明了一切:“快乐发展”。当然,这假设您使用的是 Java。尽管它确实支持包括 Python 在内的其他几种语言的插件。

于 2009-08-03T02:31:02.283 回答
0

当我需要理解别人的代码时,我经常使用 Doxygen。我在编写自己的代码时将 Vim 与 CTags 结合使用。

于 2009-08-03T03:13:46.597 回答
0

看看Kscope。它提供了一个右键菜单,为您提供任何用 C 编写的源文件集的定义、引用、调用函数、被调用函数等。它在大型项目中使用时可靠且快速。

我将它用于源导航,但对于编辑部分,我觉得geany更舒服。它不限于 C,并提供了很好的自动完成功能,它将在您键入函数时提供函数的原型。仍然有一些粗糙的边缘,但在编写 C 时,Kscope + Geany 组合是我目前最喜欢的组合。

于 2009-08-03T07:40:30.527 回答
0

我使用 Eclipse 并大量使用搜索功能(对于 C 主要是文本搜索)。

我还启用了工具提示,它可以显示文档或函数的开头。

标记出现次数也有助于在文件中查找内容。

我通常会标记我使用 TODO 注释的地方。这些在侧边栏中可见,因此在那里导航相对容易。

我还启用了行号,用于与错误消息等相关联。

我认为不可能在 Eclipse 的两个不同窗口中编辑同一个文件(但我很高兴被证明是错误的)。

于 2009-08-03T10:51:33.750 回答
0

对于大多数 Perl 和 C/C++ 编程,我使用 gvim(Vim 的 GUI 版本)。对于导航,我找到了 NERDTree、 ctags 、ack,可能还有一些用 Perl 或其他东西编写的自定义脚本。我已经在我的网站上放置了我的 Vim/gvim 配置。正如人们在那里看到的那样,我在那里有“so $VIMRUNTIME/mswin.vim”,这使得 Vim 更类似于 Windows 编辑器,并且对于来自它的人来说更熟悉。许多铁杆 vim 专家不建议使用它,但我仍然这样做。

Vim 的主页上还有许多其他插件,它们可能很有用。

于 2009-08-03T11:21:18.437 回答
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)
  )
)
于 2013-04-09T02:57:56.437 回答
-1

与弹丸集成的 Spacemacs是一个不错的选择。

可以使用 ack、grp、 ag等实用程序搜索项目文件。

(ag 比 ack 或 grep 好)

于 2016-03-14T09:25:45.003 回答