From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Romanos Skiadas Newsgroups: gmane.emacs.devel Subject: Re: New Flymake rewrite in emacs-26 Date: Wed, 11 Oct 2017 18:49:00 +0100 Message-ID: <43bcb3a1-118e-73fb-17d9-c32a74b829e3@gmail.com> References: <8760bwz5qf.fsf@gmail.com> <83infw1dkz.fsf@gnu.org> <87efqbb35x.fsf@gmail.com> <831smbqe70.fsf@gnu.org> <87tvz79h0s.fsf@gmail.com> <83wp43ov7s.fsf@gnu.org> <87bmlf9dh3.fsf@gmail.com> <83tvz7ot1o.fsf@gnu.org> <87y3oj7x60.fsf@gmail.com> <87a80y8s3s.fsf@gmail.com> <831smaoubw.fsf@gnu.org> <87y3oh7v16.fsf@gmail.com> <87k2017qed.fsf@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1507744162 20498 195.159.176.226 (11 Oct 2017 17:49:22 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 11 Oct 2017 17:49:22 +0000 (UTC) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 Cc: npostavs@users.sourceforge.net, lele@metapensiero.it, mvoteiza@udel.edu, monnier@iro.umontreal.ca, Eli Zaretskii , sdl.web@gmail.com To: =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= , emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Oct 11 19:49:15 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2L83-000488-6K for ged-emacs-devel@m.gmane.org; Wed, 11 Oct 2017 19:49:11 +0200 Original-Received: from localhost ([::1]:42077 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2L8A-0005wv-9f for ged-emacs-devel@m.gmane.org; Wed, 11 Oct 2017 13:49:18 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:56876) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2L82-0005wB-P0 for emacs-devel@gnu.org; Wed, 11 Oct 2017 13:49:12 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2L81-0000YZ-BS for emacs-devel@gnu.org; Wed, 11 Oct 2017 13:49:10 -0400 Original-Received: from mail-wm0-x236.google.com ([2a00:1450:400c:c09::236]:53790) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e2L7x-0000XN-WA; Wed, 11 Oct 2017 13:49:06 -0400 Original-Received: by mail-wm0-x236.google.com with SMTP id q132so6974246wmd.2; Wed, 11 Oct 2017 10:49:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding:content-language; bh=FLJSoEzq8s6oh9Bgm8TuT8uf9jfBo2aBbVUhGH1/zBM=; b=HKj0BLpI52O7ZsYhDrwMhgjK5aKTPjfgqV+d4teMYPiDqJGilnvEF0rrRcKQt1J6yk OErozvc22gQUD6R8jRV0TilDuDRWQHzfnokfJX7mc8sasPMlolVGBmajDr9ptU4YuR23 dxe5wKSAGtumDnGuIZ7LXsxrApmsF/lJdpHkUjqoVg8FL5lbgx2nyLk3LgB0TQvOag9x xuRqCfQIdAwRqDChHl84kS6M5NCr+ZuJnvL4yg8A/4vVAoiZyKKLLuRKvFbSEZbfe/Qx aUjVzPrAL8f43NzoUhzpSmM7JM2umuc4+Cwk21XBRtcN3OHDG/qy1hljstTi+NGoMSpY jTIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=FLJSoEzq8s6oh9Bgm8TuT8uf9jfBo2aBbVUhGH1/zBM=; b=EmlJBEy3jNQs5VuIoHLJiyExMWwJolXUFWrMDMTExA6h02A1FhEcFwiJbLuzJhP5YW Pq0kFeTWwzuK/zesu1LSEdSxUMDMtDxijjGBQoUz4T5bhapG8thCcoTa/hstA+oDEUjN imNzvpWEFLyhby2MouZ3jPhhpko6mzik8QVjfHJNu3vdADuVjS6hRTcNtxedfApFGYB6 T8lbC2/IMkUHQxqBYNU5ctvh02857Ssuv35yC77FKtbXUXPCoDLIug4unefssxoGV92A wXoarIoxikSxu/FSrWoBix+Uznbfr32vfRNZWkzPkl85BLb9hLoFIQ4U6G9nuSoLo5Kq KMMA== X-Gm-Message-State: AMCzsaUYugHonzRDHJjq3TH83gLUJct6TrcyLZa/RJTE2sFEuwR/8hYB mHXimCFR8oMW8YAHRHHg9z8= X-Google-Smtp-Source: AOwi7QCqFMRBgB8mn68uvJ+fqmeQz3loqx5FjcoDeUKFJauAHfOXRBO9J/b03yDdLP8IMzLCOU2KKw== X-Received: by 10.80.203.66 with SMTP id h2mr109552edi.54.1507744143245; Wed, 11 Oct 2017 10:49:03 -0700 (PDT) Original-Received: from [10.83.37.251] ([217.173.96.166]) by smtp.gmail.com with ESMTPSA id t43sm6822985edh.22.2017.10.11.10.49.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Oct 2017 10:49:02 -0700 (PDT) In-Reply-To: <87k2017qed.fsf@gmail.com> Content-Language: en-US X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::236 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:219381 Archived-At: Hi, This looks very interesting. I haven't tried it out yet, but the idea behind it seems to be very similar to cmake-ide[1]. Would it make sense to spin this off in its own library instead of making it flymake specific? This way other packages like company/auto-complete/flycheck can use it too. Best, Romanos [1][https://github.com/atilaneves/cmake-ide] On 11/10/17 14:41, João Távora wrote: > joaotavora@gmail.com (João Távora) writes: > >> No, I was aiming for something more generic that includes at least Emacs >> and perhaps other GNU projects. > FWIW, here's what I hacked up so far. Seems to work OK in two GNU > projects: Emacs and Hello (after ./configure, of course). > > Probably flawed, but it's a start. Feedback welcome. To test, just load > this file and M-x flymake-mode in a C file. > > Another option, as suggested previously, is to have a special Makefile > target (that'll need reconfiguring for each project, though). > > João > > ;;; flymake-gcc.el --- naive gcc Flymake backend -*- lexical-binding: t; -*- > > (defvar flymake-gcc-program "gcc" > "GCC program") > > (defun flymake--gcc-heroic-unescape (string) > (with-temp-buffer > (let ((error-buffer (current-buffer))) > (with-temp-buffer > (cond > ((zerop > ;; I suspect "shell-command" makes windows even when called > ;; from lisp. > (save-window-excursion > (shell-command > (format > "%s -Q --batch --eval \"%s\" -- %s" > (expand-file-name invocation-name > invocation-directory) > "(mapc 'print (nthcdr 4 command-line-args))" > string) > (current-buffer) > error-buffer))) > (goto-char (point-min)) > (cl-loop with eof = (make-symbol "eof") > for form = > (condition-case _err > (read (current-buffer)) > (error eof)) > while (not (eq form eof)) > collect form)) > (t > (with-current-buffer error-buffer > (error (buffer-string))))))))) > > (defvar flymake-gcc-flags 'flymake-gcc-guess-flags > "A list of flags passed to GCC. > Alternatively, a symbol naming a function called with no > arguments that should produce this list of flags, or error if it > cannot do so.") > > (defvar flymake-gcc-extra-flags '("-Wextra" "-Wall") > "A list of extra flags passed to GCC.") > > (defvar-local flymake--gcc-cached-flags nil > "Internal variable for `flymake-gcc-guess-flags'") > > (defun flymake-gcc-guess-flags (&optional trash-cache) > "Guess GCC flags for compiling current buffer " > (interactive "P") > (unless (executable-find "make") (error "Cannot find a suitable make")) > (when trash-cache (setq flymake--gcc-cached-flags nil)) > (catch 'retval > (unless (buffer-file-name) > ;; don't error and don't cache, so that when the buffer is saved > ;; we get another chance. > (throw 'retval nil)) > (when-let* ((makefile-dir > (locate-dominating-file default-directory "Makefile")) > (makefile (expand-file-name "Makefile" makefile-dir)) > (mtime (file-attribute-modification-time > (file-attributes makefile)))) > (cond > ((equal (list makefile mtime) > (cdr flymake--gcc-cached-flags)) > (when (called-interactively-p 'interactive) > (message "cached hit for flags for this buffer: %s" > (car flymake--gcc-cached-flags))) > (throw 'retval (car flymake--gcc-cached-flags))) > (t > (let* > ((sans-nothing > (file-name-nondirectory > (file-name-sans-extension > (buffer-file-name)))) > (blob (shell-command-to-string > (format "make -C %s -f %s --just-print %s.o" > makefile-dir > makefile > sans-nothing))) > (match (string-match > (format "gcc[[:space:]]+\\(\\(?:-.*\\)*\\)%s" > sans-nothing) > blob)) > (flag-string (and match > (match-string 1 blob))) > (flags (and flag-string > (flymake--gcc-heroic-unescape flag-string)))) > (when (or flags (string= "" flag-string)) > (setq flymake--gcc-cached-flags (list flags makefile mtime)) > (when (called-interactively-p 'interactive) > (message "cached miss for flags for this buffer: %s" flags)) > (throw 'retval flags)))))) > (error "Could not guess gcc flags"))) > > > (defvar-local flymake--gcc-proc nil > "Internal variable for `flymake-gcc'") > > (defun flymake-gcc (report-fn &rest _args) > "Flymake backend for GCC" > (unless (executable-find flymake-gcc-program) > (error "Cannot find a suitable gcc")) > (when (process-live-p flymake--gcc-proc) > (kill-process flymake--gcc-proc)) > (let ((source (current-buffer))) > (save-restriction > (widen) > (setq flymake--gcc-proc > (make-process > :name "gcc-flymake" > :buffer (generate-new-buffer "*gcc-flymake*") > :command `(,flymake-gcc-program > "-fsyntax-only" > ,@flymake-gcc-extra-flags > ,@(if (symbolp flymake-gcc-flags) > (funcall flymake-gcc-flags) > flymake-gcc-flags) > "-x" "c" "-") > :noquery t :connection-type 'pipe > :sentinel > (lambda (p _ev) > (when (eq 'exit (process-status p)) > (unwind-protect > (when (eq p flymake--gcc-proc) > (with-current-buffer (process-buffer p) > (goto-char (point-min)) > (cl-loop > while (search-forward-regexp > "^:\\([0-9]+\\):\\([0-9]+\\): \\(.*\\): \\(.*\\)$" > nil t) > for msg = (match-string 4) > for (beg . end) = > (flymake-diag-region > source > (string-to-number (match-string 1)) > (string-to-number (match-string 2))) > for type = (assoc-default > (match-string 3) > '(("error" . :error) > ("note" . :note) > ("warning" . :warning)) > #'string-match) > collect (flymake-make-diagnostic source beg end type msg) > into diags > finally (funcall report-fn diags)))) > ;; (display-buffer (process-buffer p)) ; use this instead of the next one for debug > (kill-buffer (process-buffer p)) > )) > ))) > (process-send-region flymake--gcc-proc (point-min) (point-max)) > (process-send-eof flymake--gcc-proc)))) > > (defun flymake--setup-gcc-flymake () > (add-hook 'flymake-diagnostic-functions 'flymake-gcc nil t)) > > (add-hook 'c-mode-hook 'flymake--setup-gcc-flymake) > > ;;; flymake-gcc.el ends here > > >