bersbersbers created this revision.
bersbersbers added a reviewer: owenpan.
bersbersbers created this object with visibility "All Users".
bersbersbers added a project: clang-format.
Herald added a project: All.
bersbersbers requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Address https://github.com/llvm/llvm-project/issues/60917


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145435

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/lib/Format/Format.cpp


Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -3534,6 +3534,25 @@
   if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
     return make_string_error("Invalid fallback style \"" + FallbackStyleName);
 
+  if (StyleName == "file") {
+    // Read style from a style comment in the code.
+    const char *Prefix{"// clang-format style="};
+    const size_t PrefixPos = Code.find(Prefix);
+
+    // Prefix found, and at start of file or preceded by white space?
+    if (PrefixPos != StringRef::npos &&
+        ((PrefixPos == 0) || (Code.substr(PrefixPos - 1, 1).ltrim() == ""))) {
+
+      // Use remainder of line as `StyleName` as if passed by `-style=...`.
+      const size_t StylePos = PrefixPos + strlen(Prefix);
+      const size_t EndOfLine = Code.find_first_of("\r\n", StylePos);
+      if (EndOfLine == StringRef::npos)
+        StyleName = Code.substr(StylePos);
+      else
+        StyleName = Code.substr(StylePos, EndOfLine - StylePos);
+    }
+  }
+
   llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1>
       ChildFormatTextToApply;
 
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -22,12 +22,15 @@
 Configuring Style with clang-format
 ===================================
 
-:program:`clang-format` supports two ways to provide custom style options:
-directly specify style configuration in the ``-style=`` command line option or
-use ``-style=file`` and put style configuration in the ``.clang-format`` or
+:program:`clang-format` supports three ways to provide custom style options:
+directly specify style configuration in the ``-style=`` command line option, or
+use ``-style=file`` and put style configuration either in a style comment
+(``// clang-format style=``) in each code file or in the ``.clang-format`` or
 ``_clang-format`` file in the project directory.
 
 When using ``-style=file``, :program:`clang-format` for each input file will
+locate the first ``// clang-format style=`` comment, if it exists, and use the
+remainder of that line as the style; if no such comment is found, it will then
 try to find the ``.clang-format`` file located in the closest parent directory
 of the input file. When the standard input is used, the search is started from
 the current directory.
@@ -100,6 +103,18 @@
 
   -style='{key1: value1, key2: value2, ...}'
 
+Similar syntax be used within the file, such as
+
+.. code-block:: console
+
+  // clang-format style={key1: value1, key2: value2, ...}
+
+or even
+
+.. code-block:: console
+
+  // clang-format style=file:<format_file_path>
+
 
 Disabling Formatting on a Piece of Code
 =======================================


Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -3534,6 +3534,25 @@
   if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
     return make_string_error("Invalid fallback style \"" + FallbackStyleName);
 
+  if (StyleName == "file") {
+    // Read style from a style comment in the code.
+    const char *Prefix{"// clang-format style="};
+    const size_t PrefixPos = Code.find(Prefix);
+
+    // Prefix found, and at start of file or preceded by white space?
+    if (PrefixPos != StringRef::npos &&
+        ((PrefixPos == 0) || (Code.substr(PrefixPos - 1, 1).ltrim() == ""))) {
+
+      // Use remainder of line as `StyleName` as if passed by `-style=...`.
+      const size_t StylePos = PrefixPos + strlen(Prefix);
+      const size_t EndOfLine = Code.find_first_of("\r\n", StylePos);
+      if (EndOfLine == StringRef::npos)
+        StyleName = Code.substr(StylePos);
+      else
+        StyleName = Code.substr(StylePos, EndOfLine - StylePos);
+    }
+  }
+
   llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1>
       ChildFormatTextToApply;
 
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -22,12 +22,15 @@
 Configuring Style with clang-format
 ===================================
 
-:program:`clang-format` supports two ways to provide custom style options:
-directly specify style configuration in the ``-style=`` command line option or
-use ``-style=file`` and put style configuration in the ``.clang-format`` or
+:program:`clang-format` supports three ways to provide custom style options:
+directly specify style configuration in the ``-style=`` command line option, or
+use ``-style=file`` and put style configuration either in a style comment
+(``// clang-format style=``) in each code file or in the ``.clang-format`` or
 ``_clang-format`` file in the project directory.
 
 When using ``-style=file``, :program:`clang-format` for each input file will
+locate the first ``// clang-format style=`` comment, if it exists, and use the
+remainder of that line as the style; if no such comment is found, it will then
 try to find the ``.clang-format`` file located in the closest parent directory
 of the input file. When the standard input is used, the search is started from
 the current directory.
@@ -100,6 +103,18 @@
 
   -style='{key1: value1, key2: value2, ...}'
 
+Similar syntax be used within the file, such as
+
+.. code-block:: console
+
+  // clang-format style={key1: value1, key2: value2, ...}
+
+or even
+
+.. code-block:: console
+
+  // clang-format style=file:<format_file_path>
+
 
 Disabling Formatting on a Piece of Code
 =======================================
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to