{"id":20126148,"url":"https://github.com/emacs-vs/codemetrics","last_synced_at":"2025-04-09T16:09:07.540Z","repository":{"id":105818360,"uuid":"607592132","full_name":"emacs-vs/codemetrics","owner":"emacs-vs","description":"Plugin shows complexity information","archived":false,"fork":false,"pushed_at":"2025-02-26T10:12:54.000Z","size":199,"stargazers_count":68,"open_issues_count":4,"forks_count":7,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-09T16:09:02.562Z","etag":null,"topics":["cognitive","complexity","elisp","emacs"],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emacs-vs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["emacs-vs","jcs090218"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2023-02-28T09:34:42.000Z","updated_at":"2025-03-04T12:28:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"69576d93-317e-4f8a-b8ce-b8799f895bb3","html_url":"https://github.com/emacs-vs/codemetrics","commit_stats":{"total_commits":91,"total_committers":4,"mean_commits":22.75,"dds":0.1208791208791209,"last_synced_commit":"b0b23050ab097f8f25727ebd9ace400b16920080"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emacs-vs%2Fcodemetrics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emacs-vs%2Fcodemetrics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emacs-vs%2Fcodemetrics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emacs-vs%2Fcodemetrics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emacs-vs","download_url":"https://codeload.github.com/emacs-vs/codemetrics/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248065283,"owners_count":21041871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cognitive","complexity","elisp","emacs"],"created_at":"2024-11-13T20:14:00.283Z","updated_at":"2025-04-09T16:09:07.517Z","avatar_url":"https://github.com/emacs-vs.png","language":"Emacs Lisp","readme":"[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n[![JCS-ELPA](https://raw.githubusercontent.com/jcs-emacs/badges/master/elpa/v/codemetrics.svg)](https://jcs-emacs.github.io/jcs-elpa/#/codemetrics)\n\u003ca href=\"#\"\u003e\u003cimg align=\"right\" src=\"./etc/logo.png\" width=\"20%\"\u003e\u003c/a\u003e\n\n# Code Metrics\n\u003e Plugin shows complexity information\n\n[![CI](https://github.com/emacs-vs/codemetrics/actions/workflows/test.yml/badge.svg)](https://github.com/emacs-vs/codemetrics/actions/workflows/test.yml)\n\n\u003cimg src=\"./etc/demo.gif\" /\u003e\n\nThis plugin implements live calculation of the **Cognitive Complexity** metric,\nwhich was proposed by G. Ann Campbell in\n[Cognitive Complexity - A new way of measuring understandability](https://www.sonarsource.com/docs/CognitiveComplexity.pdf)\n(c) SonarSource S.A. 2016-2021, Switzerland.\n\n\u003e **Abstract:** Cyclomatic Complexity was initially formulated as a measurement\n\u003e of the \"testability and maintainability\" of the control flow of a module.\n\u003e While it excels at measuring the former, its underlying mathematical model is\n\u003e unsatisfactory at producing a value that measures the latter. This white paper\n\u003e describes a new metric that breaks from the use of mathematical models to\n\u003e evaluate code in order to remedy Cyclomatic Complexity’s shortcomings and\n\u003e produce a measurement that more accurately reflects the relative difficulty of\n\u003e understanding, and therefore of maintaining methods, classes, and applications.\n\n\u003c!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc --\u003e\n**Table of Contents**\n\n- [Code Metrics](#code-metrics)\n  - [💾 Installation](#💾-installation)\n    - [🔍 Method 1. with `straight.el` and `use-package`:](#🔍-method-1-with-straightel-and-use-package)\n    - [🔍 Method 2. Manual](#🔍-method-2-manual)\n  - [🖥 Usage](#🖥-usage)\n    - [📚 Use it as a library](#📚-use-it-as-a-library)\n  - [🔨 Supported languages](#🔨-supported-languages)\n  - [📝 Customization](#📝-customization)\n    - [⚪ Analysis on new nodes](#⚪-analysis-on-new-nodes)\n      - [❔ Example](#❔-example)\n    - [🔍 Writing new analysis functions](#🔍-writing-new-analysis-functions)\n  - [🔗 References](#🔗-references)\n  - [🛠️ Contribute](#🛠️-contribute)\n    - [🔬 Development](#🔬-development)\n    - [❓ How to add an analysis rules?](#❓-how-to-add-an-analysis-rules)\n      - [🔍 Where can I look for tree-sitter node?](#🔍-where-can-i-look-for-tree-sitter-node)\n  - [⚜️ License](#⚜️-license)\n\n\u003c!-- markdown-toc end --\u003e\n\n## 💾 Installation\n\n### 🔍 Method 1. with `straight.el` and `use-package`:\n\n```elisp\n(use-package codemetrics\n  :straight (codemetrics :type git :host github :repo \"jcs-elpa/codemetrics\"))\n```\n\n### 🔍 Method 2. Manual\n\n```sh\ngit clone https://github.com/jcs-elpa/codemetrics /path/to/lib\n```\n\nthen in Emacs:\n\n```elisp\n(add-to-list 'load-path \"/path/to/lib\")\n(require 'codemetrics)\n```\n\nor\n\n```elisp\n(use-package codemetrics\n  :load-path \"/path/to/lib\")\n```\n\n## 🖥 Usage\n\nThe simplest way to start using this package:\n\n```elisp\n(codemetrics-mode 1)\n```\n\n### 📚 Use it as a library\n\nThese are functions you can use to analyze:\n\n| Functions             | Description                        |\n|-----------------------|------------------------------------|\n| `codemetrics-analyze` | Analyze a string with `major-mode` |\n| `codemetrics-region`  | Analyze region                     |\n| `codemetrics-buffer`  | Analyze the whole buffer           |\n\nAll these functions return the score data indicating the complexity.\n\n## 🔨 Supported languages\n\u003e ⚠️ Please sort these two lists alphabetically!\n\nThese languages are fairly complete:\n\n- Bash\n- C / C++ / C#\n- Elisp\n- Go\n- Java / JavaScript / JSX / Julia\n- Kotlin\n- Lua\n- PHP / Python\n- Ruby / Rust\n- Swift\n- TypeScript / TSX\n\nThese languages are in development:\n\n- Agda\n- Elm\n- Elixir\n- OCaml\n- Scala (upstream, kinda buggy)\n\n## 📝 Customization\n\nAlthough codemetrics aims to have good analysis rules out of the box for all\nsupported definitions, people will indubitably have their own preferences or\ndesired functionality. The following section outlines how to add your own\nanalysis definitions and analysis functions to make codemetrics work for you.\nIf there are any improvements you find for existing or new languages, please do\nraise a PR so that others may benefit from better analysis in the future!\n\n### ⚪ Analysis on new nodes\n\nCode-Metrics defines all its analysis definitions in the variable\n`codemetrics-rules` which is an alist with the key of the alist being the\nmode and the value being another alist of analysis definitions.\n\n```elisp\n;; Example of codemetrics-rules' structure\n'((c-mode      . c-analysis-definitions)  ; \u003clanguage\u003e-analysis-definitions is structured as shown below\n  (csharp-mode . csharp-analysis-definitions)\n  (go-mode     . go-analysis-definitions)\n  (scala-mode  . scala-analysis-definitions)\n  ...)\n\n;; Examle of a analysis definition alist\n(setq csharp-analysis-definitions\n    (if_statement   . (1 t))\n    (\"\u0026\u0026\"           . codemetrics-rules--logical-operators))\n```\n\nSo you can select whatever node that you want to analyze on it.\n\nTo find what node you'll want to analyze, refer to the\n[tree-sitter documentation](https://emacs-tree-sitter.github.io/getting-started/#view-the-syntax-tree)\nabout viewing nodes. `tree-sitter-debug` and `tree-sitter-query-builder`\nare both very useful for this.\n\n#### ❔ Example\n\nLet's look at a quick example of adding a new analysis definition. Let's say you\nwant to add analysis to `go-mode`'s `if_statement`. The analysis definition that\nis needed will be `'(if_statement . (1 t))`. To add this to the\n`codemetrics-rules`, you can do something like the following.\n\n```emacs-lisp\n(push '(if_statement . (1 t)) (alist-get 'go-mode codemetrics-rules))\n```\n\nNow the new analysis definition should be usable by codemetrics!\n\n### 🔍 Writing new analysis functions\n\nFor more complex analysis, you can write your own analysis rules!\n\n- `node` - (optional) the targeted tree-sitter node, in this example,\n`if_statement` will be the targeting node.\n- `depth` - (optional) current depth of from the root tree.\n- `nested` - (optional) current nested level apply from current complexity\nalgorithm.\n\nThen the function needs to return an integer represent the score and a\nboolean represent increment of the nested level in the form\n`(score-to-add . nested?)`. This can be useful if you want to add extra\nconditional logic onto your analysis.\n\nAs an example of an analysis function, take a look at the definition of the\nbasic `codemetrics-rules--class-declaration`.\n\n```elisp\n(defun codemetrics-rules--class-declaration (_node depth _nested)\n  \"...\"\n  (codemetrics-with-complexity\n    (if (\u003c 1 depth)  ; if class inside class,\n        '(1 nil)     ; we score 1, but don't increase nested level\n      '(0 nil))\n    '(1 nil)))\n```\n\n## 🔗 References\n\n- [codemetrics](https://github.com/kisstkondoros/codemetrics)\n- [resharper-cognitivecomplexity](https://github.com/matkoch/resharper-cognitivecomplexity)\n- [gocognit](https://github.com/uudashr/gocognit)\n\n## 🛠️ Contribute\n\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)\n[![Elisp styleguide](https://img.shields.io/badge/elisp-style%20guide-purple)](https://github.com/bbatsov/emacs-lisp-style-guide)\n[![Donate on paypal](https://img.shields.io/badge/paypal-donate-1?logo=paypal\u0026color=blue)](https://www.paypal.me/jcs090218)\n[![Become a patron](https://img.shields.io/badge/patreon-become%20a%20patron-orange.svg?logo=patreon)](https://www.patreon.com/jcs090218)\n\nIf you would like to contribute to this project, you may either\nclone and make pull requests to this repository. Or you can\nclone the project and establish your own branch of this tool.\nAny methods are welcome!\n\n### 🔬 Development\n\nTo run the test locally, you will need the following tools:\n\n- [Eask](https://emacs-eask.github.io/)\n- [Make](https://www.gnu.org/software/make/) (optional)\n\nInstall all dependencies and development dependencies:\n\n```sh\neask install-deps --dev\n```\n\nTo test the package's installation:\n\n```sh\neask package\neask install\n```\n\nTo test compilation:\n\n```sh\neask compile\n```\n\n**🪧 The following steps are optional, but we recommend you follow these lint results!**\n\nThe built-in `checkdoc` linter:\n\n```sh\neask lint checkdoc\n```\n\nThe standard `package` linter:\n\n```sh\neask lint package\n```\n\n*📝 P.S. For more information, find the Eask manual at https://emacs-eask.github.io/.*\n\n### ❓ How to add an analysis rules?\n\nWhen adding a new analysis rules, add the analysis definition function to\n`codemetrics.el` itself near where the other rules functions live and then add\nthe parser to `codemetrics-rules.el` file. Finally, if you are adding support\nfor a new language, remember to add it to the `codemetrics-rules` variable.\n\nWhen creating a new parser, name it `codemetrics-rules-\u003clanguage\u003e`.\n\nWhen creating a new analysis function, name it\n`codemetrics-rules-\u003clanguage\u003e-\u003cfeature\u003e` or something similar.\n\n#### 🔍 Where can I look for tree-sitter node?\n\nHere are some techniques for finding your desired nodes in tree-sitter.\n\nTo look for the correct node you have three options:\n\n- look at the `tree-sitter-[lang]/grammar.js` implementation. In the above\n  example, `if_statement` node is defined in the\n  [tree-sitter-c-sharp](https://github.com/tree-sitter/tree-sitter-c-sharp)'s\n  `grammar.js` file\n- open a file of your language choice in emacs and `M-x tree-sitter-debug-mode`.\n  This will display the whole s-expr representing your file\n- `(message \"%S\" (tsc-node-to-sexp))` in your function to display what your\n  function is seeing\n\n\u003e ⚠️ Warning\n\u003e\n\u003e Make sure you look into the correct repository. Repositories are managed\n\u003e under [tree-sitter-langs](https://github.com/emacs-tree-sitter/tree-sitter-langs)'s\n\u003e using git submodule. Some tree-sitter module aren't using the latest version!\n\n## ⚜️ License\n\nThis program is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program.  If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n\nSee [`LICENSE`](./LICENSE.txt) for details.\n","funding_links":["https://github.com/sponsors/emacs-vs","https://github.com/sponsors/jcs090218","https://www.paypal.me/jcs090218","https://www.patreon.com/jcs090218"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femacs-vs%2Fcodemetrics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femacs-vs%2Fcodemetrics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femacs-vs%2Fcodemetrics/lists"}