File indexing completed on 2024-05-19 04:00:11

0001 /*
0002     Helper String Functions (copied from cstyle.js to be reused by other indenters)
0003     SPDX-FileCopyrightText: Alex Turbov <i.zaufi@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 
0008 //BEGIN Utils
0009 /**
0010  * \brief Print or suppress debug output depending on \c debugMode variable.
0011  *
0012  * The mentioned \c debugMode supposed to be defined by a particular indenter
0013  * (external code).
0014  */
0015 function dbg()
0016 {
0017     if (debugMode)
0018     {
0019         debug.apply(this, arguments);
0020     }
0021 }
0022 
0023 /**
0024  * \return \c true if attribute at given position is a \e Comment
0025  *
0026  * \note C++ highlighter use \em RegionMarker for special comments,
0027  * so it must be counted as well...
0028  *
0029  * \todo Provide an "overload" which accepts a \c Cursor
0030  */
0031 function isComment(line, column)
0032 {
0033     // Check if we are not withing a comment
0034     var c = new Cursor(line, column);
0035     var mode = document.attributeName(c);
0036     dbg("isComment: Check mode @ " + c + ": " + mode);
0037     return mode.startsWith("Doxygen")
0038       || mode.startsWith("Alerts")
0039       || document.isComment(c)
0040       || document.isRegionMarker(c)
0041       ;
0042 }
0043 
0044 /**
0045  * \return \c true if attribute at given position is a \e String
0046  *
0047  * \todo Provide an "overload" which accepts a \c Cursor
0048  */
0049 function isString(line, column)
0050 {
0051     // Check if we are not withing a string
0052     var c = new Cursor(line, column);
0053     var mode = document.attributeName(c);
0054     dbg("isString: Check mode @ " + c + ": " + mode);
0055     return document.isString(c) || document.isChar(c);
0056 }
0057 
0058 /**
0059  * \return \c true if attribute at given position is a \e String or \e Comment
0060  *
0061  * \note C++ highlighter use \e RegionMarker for special comments,
0062  * soit must be counted as well...
0063  *
0064  * \todo Provide an "overload" which accepts a \c Cursor
0065  */
0066 function isStringOrComment(line, column)
0067 {
0068     // Check if we are not withing a string or a comment
0069     var c = new Cursor(line, column);
0070     var mode = document.attributeName(c);
0071     dbg("isStringOrComment: Check mode @ " + c + ": " + mode);
0072     return mode.startsWith("Doxygen")
0073       || mode.startsWith("Alerts")
0074       || document.isString(c)
0075       || document.isChar(c)
0076       || document.isComment(c)
0077       || document.isRegionMarker(c)
0078       ;
0079 }
0080 
0081 /**
0082  * Split a given text line by comment into parts \e before and \e after the comment
0083  * \return an object w/ the following fields:
0084  *   \li \c hasComment -- boolean: \c true if comment present on the line, \c false otherwise
0085  *   \li \c before -- text before the comment
0086  *   \li \c after -- text of the comment
0087  *
0088  * \todo Possible it would be quite reasonable to analyze a type of the comment:
0089  * Is it C++ or Doxygen? Is it single or w/ some text before?
0090  */
0091 function splitByComment(line)
0092 {
0093     var before = "";
0094     var after = "";
0095     var text = document.line(line);
0096     dbg("splitByComment: text='"+text+"'");
0097 
0098     /// \note Always ask a comment marker for Normal Text attribute
0099     /// of the current syntax, but not for a given line, cuz latter
0100     /// can be a Doxygen comment, which do not have a comment marker
0101     /// defined at all...
0102     var comment_marker = document.commentMarker(0);
0103     var text = document.line(line);
0104     var found = false;
0105     for (
0106         var pos = text.indexOf(comment_marker)
0107       ; pos != -1
0108       ; pos = text.indexOf(comment_marker, pos + 1)
0109       )
0110     {
0111         // Check attribute to be sure...
0112         if (isComment(line, pos))
0113         {
0114             // Got it!
0115             before = text.substring(0, pos);
0116             after = text.substring(pos + comment_marker.length, text.length);
0117             found = true;
0118             break;
0119         }
0120     }
0121     // If no comment actually found, then set text before to the original
0122     if (!found)
0123         before = text;
0124     dbg("splitByComment result: hasComment="+found+", before='"+before+"', after='"+after+"'");
0125     return {hasComment: found, before: before, after: after};
0126 }
0127 
0128 /**
0129  * \brief Remove possible comment from text
0130  */
0131 function stripComment(line)
0132 {
0133     var result = splitByComment(line);
0134     if (result.hasComment)
0135         return result.before.rtrim();
0136     return result.before.rtrim();
0137 }
0138 
0139 /**
0140  * Add a character \c c to the given position if absent.
0141  * Set new cursor position to the next one after the current.
0142  *
0143  * \return \c true if a desired char was added
0144  *
0145  * \todo Provide an "overload" which accepts a \c Cursor
0146  */
0147 function addCharOrJumpOverIt(line, column, char)
0148 {
0149     // Make sure there is a space at given position
0150     dbg("addCharOrJumpOverIt: checking @Cursor("+line+","+column+"), c='"+document.charAt(line, column)+"'");
0151     var result = false;
0152     if (document.lineLength(line) <= column || document.charAt(line, column) != char)
0153     {
0154         document.insertText(line, column, char);
0155         result = true;
0156     }
0157     /// \todo Does it really needed?
0158     view.setCursorPosition(line, column + 1);
0159     return result;
0160 }
0161 
0162 /**
0163  * Check if a character right before cursor is the very first on the line
0164  * and the same as a given one.
0165  *
0166  * \todo Provide an "overload" which accepts a \c Cursor
0167  */
0168 function justEnteredCharIsFirstOnLine(line, column, char)
0169 {
0170     return document.firstChar(line) == char && document.firstColumn(line) == (column - 1);
0171 }
0172 //END Utils
0173 
0174 /**
0175  * \todo Unit tests! How?
0176  */
0177 
0178 // kate: space-indent on; indent-width 4; replace-tabs on;