unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Filippo Argiolas <filippo.argiolas@gmail.com>
To: Juri Linkov <juri@linkov.net>
Cc: 74448@debbugs.gnu.org
Subject: bug#74448: 30.0.92; c-ts-mode outlines only work with GNU or emacs style
Date: Thu, 21 Nov 2024 10:47:35 +0100	[thread overview]
Message-ID: <m2o7287waw.fsf@gmail.com> (raw)
In-Reply-To: <875xoh9gnw.fsf@mail.linkov.net>

Juri Linkov <juri@linkov.net> writes:

>> Hi, I've been playing with the new treesitter based outline minor mode
>> and c-ts-mode.
>>
>> It seems that `outline-hide-subtree' is only working properly when code
>> is formatted with either GNU or emacs style.
>>
>> To test try it with a function where the function declarator is preceded on the
>> same line by either type or storage class and type. It will fold the
>> function heading instead of the function body.
>>
>> Problem seems `c-ts-mode--outline-predicate' only checks for
>> function_declarator nodes at the beginning of line (like in GNU coding
>> style) but other coding style will start the function line with either
>> storage class (e.g. static) or type.
>>
>> Something like this seems to work a little better:
>>
>> (defun c-ts-mode--outline-predicate (node)
>>   "Match outlines on lines with function names."
>>   (or (and (or (equal (treesit-node-type node) "function_declarator")
>>                (equal (treesit-node-type node) "storage_class_specifier")
>>                (equal (treesit-node-type node) "primitive_type")
>>                (equal (treesit-node-type node) "type_identifier"))
>>            (equal (treesit-node-type (treesit-node-parent node))
>>                   "function_definition"))
>>       ;; DEFUNs in Emacs sources.
>>       (and c-ts-mode-emacs-sources-support
>>            (c-ts-mode--emacs-defun-p node))))
>>
>> But it kind of breaks GNU style by adding two outlines per function
>> definition. Also it seems a bit ugly to enumerate all the node types by
>> hand, there probably is a nicer way to detect a line with a
>> function_declarator not at bol.
>>
>> Any better idea?
>
> Could you please send a few of short examples of each style.
> This would help to make a better decision.
> And later these examples could be added to tests.

You should be able to see it with this example

int bar(void) {
  return 1;
}

static int
foo (int bar) {
  return 2;
}

int main(void) {
  return 3;
}

If you go to the third function and call `outline-hide-subtree' it
replaces the function name with an ellipsis.

Now if you call `outline-show-all' and try to collapse the second
function (GNU style) it will show

foo (int bar) {...

which looks correct to me.

If you show all again and collapse the first one it will do nothing and
say "Before the first heading". This while still showing the outline
icon in the margin.

At the moment I am experimenting with this solution (DEFUN part omitted
for brevity) but it's probably missing some edge case I am not aware of:

(defun c-ts-mode--outline-predicate (node)
  "Match outlines on lines with function names."
  (when-let* ((decl (treesit-node-child-by-field-name
                     (treesit-node-parent node) "declarator"))
              (node-pos (treesit-node-start node))
              (decl-pos (treesit-node-start decl))
              (eol (save-excursion (goto-char node-pos) (line-end-position))))
    (and (equal (treesit-node-type decl) "function_declarator")
         (<= node-pos decl-pos)
         (< decl-pos eol))))

Idea is to match a function declarator in the same line as `node' no
matter what node is at bol.

Ciao,
Filippo





      reply	other threads:[~2024-11-21  9:47 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-20 22:22 bug#74448: 30.0.92; c-ts-mode outlines only work with GNU or emacs style Filippo Argiolas
2024-11-21  7:42 ` Juri Linkov
2024-11-21  9:47   ` Filippo Argiolas [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m2o7287waw.fsf@gmail.com \
    --to=filippo.argiolas@gmail.com \
    --cc=74448@debbugs.gnu.org \
    --cc=juri@linkov.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).