<commit_before>/*
 * Copyright (c) 2004 Nu Echo Inc.
 * 
 * This is free software. For terms and warranty disclaimer, see ./COPYING
 */
package org.schemeway.plugins.schemescript.indentation;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.preference.*;
import org.eclipse.jface.text.*;
import org.schemeway.plugins.schemescript.*;
import org.schemeway.plugins.schemescript.parser.*;
import org.schemeway.plugins.schemescript.preferences.*;

public class SchemeIndentationStrategy implements IAutoEditStrategy {
    private SexpNavigator mExplorer;
    private SchemeIndentationManager mIndentationManager;

    public SchemeIndentationStrategy(SchemeIndentationManager indentManager) {
        Assert.isNotNull(indentManager);
        mIndentationManager = indentManager;
    }

    public void dispose() {
        mExplorer.dispose();
        mExplorer = null;
    }

    public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
        initializeStrategy(document);
        if (command.length == 0
            && command.text != null
            && TextUtilities.endsWith(document.getLegalLineDelimiters(), command.text) != -1) {
            try {
                IRegion lineInfo = document.getLineInformationOfOffset(command.offset);
                String line = document.get(lineInfo.getOffset(), lineInfo.getLength());
                String prefix = CommentPreferences.getCommentPrefix();
                IPreferenceStore store = SchemeScriptPlugin.getDefault().getPreferenceStore();
                boolean continueComment = store.getBoolean(CommentPreferences.COMMENT_CONTINUE);

                // make sure we are not at the start of the line, in which case
                // we simply insert a line break
                if (continueComment && line.startsWith(prefix) && (!line.equals(prefix + " "))
                        && command.offset != lineInfo.getOffset()) {
                    command.text = command.text + prefix + " ";
                }
                else {
                    autoIndentAfterNewLine(document, command);
                }
            }
            catch (BadLocationException exception) {

            }
        }
    }

    private void initializeStrategy(IDocument document) {
        if (mExplorer == null || document != mExplorer.getDocument()) {
            if (mExplorer != null)
                mExplorer.dispose();
            mExplorer = new SexpNavigator(document);
        }
    }

    private void autoIndentAfterNewLine(IDocument document, DocumentCommand command) {
        try {
            int indentation = findIndentation(new SchemeIndentationContext(mExplorer,
                                                                           mIndentationManager,
                                                                           command.offset));
            if (indentation > 0) {
                StringBuffer buffer = new StringBuffer(command.text);

                for (int i = 0; i < indentation; i++)
                    buffer.append(' ');
                command.text = buffer.toString();
            }
            removeLeadingSpaces(document, command);
        }
        catch (BadLocationException exception) {
        }
    }

    public static int findIndentation(SchemeIndentationContext context) throws BadLocationException {
        int indentation = 0;
        SexpNavigator explorer = context.getExplorer();
        IDocument document = explorer.getDocument();

        if (explorer.backwardSexpression(context.getOffset())) {
            // There is an S-expression before the insertion point
            int previousStart = context.getExplorer().getSexpStart();

            if (explorer.upSexpression(previousStart)) {
                // We are inside an S-expression
                int outerStart = explorer.getSexpStart();
                char ch = document.getChar(outerStart);
                while (!SchemeScannerUtilities.isOpeningParenthesis(ch)) {
                    outerStart++;
                    ch = document.getChar(outerStart);
                }
                if (SchemeScannerUtilities.isOpeningBracket(ch)) {
                	return findColumn(document, outerStart) + 1;	
                }

                explorer.downSexpression(outerStart);
                explorer.forwardSexpression(explorer.getSexpStart());
                // we have a form '(symbol ...)'
                if (explorer.getSexpType() == SexpNavigator.TYPE_SYMBOL) {
                    // Find the indentation scheme
                    String text = explorer.getText();
                    IndentationRule scheme = context.getManager().getFunction(text);

                    indentation = findIndentationFromScheme(context.getExplorer(),
                                                            context.getOffset(),
                                                            previousStart,
                                                            outerStart,
                                                            scheme);
                }
                else if (explorer.getSexpType() == SexpNavigator.TYPE_LIST) {
                    indentation = findColumn(document, explorer.getSexpStart());
                }
                else
                    indentation = findColumn(document, previousStart);
            }
            else {
                indentation = findColumn(document, previousStart);
            }
        }
        else if (explorer.upSexpression(context.getOffset())) {
            indentation = findColumn(document, explorer.getSexpStart()) + 1;
        }
        return indentation;
    }

    private static int findIndentationFromScheme(SexpNavigator explorer,
                                                 int insertionOffset,
                                                 int previousStart,
                                                 int outerStart,
                                                 IndentationRule scheme) throws BadLocationException {
        int indentation;
        String type = scheme.getCategory();
        IDocument document = explorer.getDocument();

        if (type == IndentationRule.DEFAULT) {
            // find the first no
            int lineStart = explorer.getDocument().getLineInformationOfOffset(previousStart).getOffset();
            int offset = previousStart;

            while (explorer.backwardSexpression(offset) && offset > lineStart) {
                previousStart = offset;
                offset = explorer.getSexpStart();
            }
            indentation = findColumn(document, previousStart);
        }
        else if (type == IndentationRule.NONE) {<commit_msg>Constant lists are now properly indented.<commit_after>/*
 * Copyright (c) 2004 Nu Echo Inc.
 * 
 * This is free software. For terms and warranty disclaimer, see ./COPYING
 */
package org.schemeway.plugins.schemescript.indentation;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.preference.*;
import org.eclipse.jface.text.*;
import org.schemeway.plugins.schemescript.*;
import org.schemeway.plugins.schemescript.parser.*;
import org.schemeway.plugins.schemescript.preferences.*;

public class SchemeIndentationStrategy implements IAutoEditStrategy {
    private SexpNavigator mExplorer;
    private SchemeIndentationManager mIndentationManager;

    public SchemeIndentationStrategy(SchemeIndentationManager indentManager) {
        Assert.isNotNull(indentManager);
        mIndentationManager = indentManager;
    }

    public void dispose() {
        mExplorer.dispose();
        mExplorer = null;
    }

    public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
        initializeStrategy(document);
        if (command.length == 0
            && command.text != null
            && TextUtilities.endsWith(document.getLegalLineDelimiters(), command.text) != -1) {
            try {
                IRegion lineInfo = document.getLineInformationOfOffset(command.offset);
                String line = document.get(lineInfo.getOffset(), lineInfo.getLength());
                String prefix = CommentPreferences.getCommentPrefix();
                IPreferenceStore store = SchemeScriptPlugin.getDefault().getPreferenceStore();
                boolean continueComment = store.getBoolean(CommentPreferences.COMMENT_CONTINUE);

                // make sure we are not at the start of the line, in which case
                // we simply insert a line break
                if (continueComment && line.startsWith(prefix) && (!line.equals(prefix + " "))
                        && command.offset != lineInfo.getOffset()) {
                    command.text = command.text + prefix + " ";
                }
                else {
                    autoIndentAfterNewLine(document, command);
                }
            }
            catch (BadLocationException exception) {

            }
        }
    }

    private void initializeStrategy(IDocument document) {
        if (mExplorer == null || document != mExplorer.getDocument()) {
            if (mExplorer != null)
                mExplorer.dispose();
            mExplorer = new SexpNavigator(document);
        }
    }

    private void autoIndentAfterNewLine(IDocument document, DocumentCommand command) {
        try {
            int indentation = findIndentation(new SchemeIndentationContext(mExplorer,
                                                                           mIndentationManager,
                                                                           command.offset));
            if (indentation > 0) {
                StringBuffer buffer = new StringBuffer(command.text);

                for (int i = 0; i < indentation; i++)
                    buffer.append(' ');
                command.text = buffer.toString();
            }
            removeLeadingSpaces(document, command);
        }
        catch (BadLocationException exception) {
        }
    }

    public static int findIndentation(SchemeIndentationContext context) throws BadLocationException {
        int indentation = 0;
        SexpNavigator explorer = context.getExplorer();
        IDocument document = explorer.getDocument();

        if (explorer.backwardSexpression(context.getOffset())) {
            // There is an S-expression before the insertion point
            int previousStart = context.getExplorer().getSexpStart();

            if (explorer.upSexpression(previousStart)) {
                // We are inside an S-expression
                int outerStart = explorer.getSexpStart();
                char ch = document.getChar(outerStart);
                char firstCh = ch;
                while (!SchemeScannerUtilities.isOpeningParenthesis(ch)) {
                    outerStart++;
                    ch = document.getChar(outerStart);
                }
                if (isConstantListPrefix(firstCh) || SchemeScannerUtilities.isOpeningBracket(ch)) {
                	return findColumn(document, outerStart) + 1;	
                }

                explorer.downSexpression(outerStart);
                explorer.forwardSexpression(explorer.getSexpStart());
                // we have a form '(symbol ...)'
                if (explorer.getSexpType() == SexpNavigator.TYPE_SYMBOL) {
                    // Find the indentation scheme
                    String text = explorer.getText();
                    IndentationRule scheme = context.getManager().getFunction(text);

                    indentation = findIndentationFromScheme(context.getExplorer(),
                                                            context.getOffset(),
                                                            previousStart,
                                                            outerStart,
                                                            scheme);
                }
                else if (explorer.getSexpType() == SexpNavigator.TYPE_LIST) {
                    indentation = findColumn(document, explorer.getSexpStart());
                }
                else
                    indentation = findColumn(document, previousStart);
            }
            else {
                indentation = findColumn(document, previousStart);
            }
        }
        else if (explorer.upSexpression(context.getOffset())) {
            indentation = findColumn(document, explorer.getSexpStart()) + 1;
        }
        return indentation;
    }

	/*
	 * Returns true for characters starting a constant list (currently vector, quoted and back-quoted list) 
	 */
	private static boolean isConstantListPrefix(char firstCh) {
		return firstCh == '\'' || firstCh == '`' || firstCh == '#';
	}

    private static int findIndentationFromScheme(SexpNavigator explorer,
                                                 int insertionOffset,
                                                 int previousStart,
                                                 int outerStart,
                                                 IndentationRule scheme) throws BadLocationException {
        int indentation;
        String type = scheme.getCategory();
        IDocument document = explorer.getDocument();

        if (type == IndentationRule.DEFAULT) {
            // find the first no
            int lineStart = explorer.getDocument().getLineInformationOfOffset(previousStart).getOffset();
            int offset = previousStart;

            while (explorer.backwardSexpression(offset) && offset > lineStart) {
                previousStart = offset;
                offset = explorer.getSexpStart();
            }
            indentation = findColumn(document, previousStart);
        }
        else if (type == IndentationRule.NONE) {
{'fraction_non_alphanumeric': 0.08290946083418108, 'fraction_numerical': 0.0015986048539456475, 'mean_word_length': 1.6528527370855821, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 44, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6724852', 'n_tokens_mistral': 3236, 'n_tokens_neox': 3018, 'n_words': 686}