How to insert a comma in an array literal?

Hi,

I know this is a very specific question, but I can't figure it out. My situation is that I have a JavaScript array literal with line breaks like this:

[
    'a',
    'b',
    'c'
].

I would like to add a new element to the end, so I need to add the code fragment ",\n'd'".

I add elements elsewhere in my plugin but those are complete expressions or statements. I don't know the best way to add this fragment. Any help is appreciated.

5 comments

Hi Chris,
do you mean something like this?

jsCode = jsCode.substring(0, jsCode.lastIndexOf("'\n]") ) + ",\n\t'd'\n]";


Greetings, Kay

0

Kay,

Let me clarify -- I'm trying to create PsiElements that represent the code fragment and insert that into the existing Psi tree that represents the array. There are methods to create the PsiElements for expressions and statements, but I'm trying to just create a 'fragment'.

0

Hi Chris,

You can insert text directly into the document if you like - find the element corresponding to your insertion point ('c' in this case) and then use Document.insertString(element.getTextRange().getEndOffset(), ",\n'd'"). You can then call PsiDocumentManager.commitDocument(document) to rebuild the PSI tree and reformat the whole block using CodeStyleManager.reformatText().

Cheers,
Colin

0

There are many ways. Here is one I used.

Given

PsiElement element;


and

String replacement;



Document doc = PsiDocumentManager.getInstance(element.getProject()).getDocument(element.getContainingFile());

doc.replaceString(element.getTextOffset(), element.getTextOffset() + element.getTextLength(), replacement);



You can also, just create a fragment Psi tree with your new code and replace it directly in the Psi tree using API's on the Psi clases.

Excerpt: (parent is some PsiElement)

final PsiElement newWhiteSpace = factory.createCommentFromText("-- " + lines[i].trim() + '\n', parent);

parent.addAfter(nextComment, comment);



Here is a real exmaple from my plugin: It takes an assignment statment that can have any number of expressions on either side, and equalizes it

a, b, c = 1

becomes

a, b, c, = 1, nil, nil

Notice I don't add any ',' and just add the 'nil'  as an expression.

        @Override         protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {             final LuaAssignmentStatement assign = (LuaAssignmentStatement) descriptor.getPsiElement();             final LuaIdentifierList identifierList = assign.getLeftExprs();             final LuaExpressionList expressionList = assign.getRightExprs();             final PsiElement lastExpr = expressionList.getLastChild();             final int leftCount = identifierList.count();             final int rightCount = expressionList.count();             if (tooManyExprs) {                 for (int i = rightCount - leftCount; i > 0; i--) {                     LuaExpression extraExpression = LuaPsiElementFactory.getInstance(project).createExpressionFromText("_");                     assert extraExpression != null : "Failed to create extra expression";                     identifierList.addAfter(extraExpression, lastExpr);                 }             } else {                 for (int i = leftCount - rightCount; i > 0; i--) {                     LuaExpression nilExpression = LuaPsiElementFactory.getInstance(project).createExpressionFromText("nil");                     assert nilExpression != null : "Failed to create nil expression";                     expressionList.addAfter(nilExpression, lastExpr);                 }             }         }


Here is where ',' gets added.

    @Override     public PsiElement addAfter(@NotNull PsiElement element, PsiElement anchor) throws IncorrectOperationException {         List<LuaExpression> exprs = getLuaExpressions();         if (exprs.size() == 0) {             add(element);         } else {             element = super.addAfter(element, anchor);             final ASTNode astNode = getNode();             if (anchor != null) {                 astNode.addLeaf(COMMA, ",", element.getNode());             } else {                 astNode.addLeaf(COMMA, ",", element.getNextSibling().getNode());             }             CodeStyleManager.getInstance(getManager().getProject()).reformat(this);         }         return element;     }


Sometimes it makes more sense to manipulate the Psi tree, and sometimes just using text makes sense. Learn both ways, but the whole semantic editor concepts rests fundamentally on being able to perform manipulations on the code structure and not the text itself. It may not make sense for your use case - but it is worth learning.

0

Thanks Jon, I didn't know you could just add leaf nodes like that in your last example. I was able to use that method to achieve what I needed.

0

Please sign in to leave a comment.