Skip to main content

Overview

Android Code Studio features a powerful code editor built on top of the Sora Editor framework, providing a complete coding experience on Android devices. The editor supports multiple languages including Java, Kotlin, XML, Groovy, and more with advanced features like syntax highlighting, code completion, and real-time diagnostics.

Core Capabilities

The editor is designed with modularity in mind, exposing functionality through the IEditor interface for seamless integration across the IDE.

Text Manipulation

Selection Control

Set cursor position, select ranges, and navigate through code programmatically

Content Modification

Replace content, append text, and validate text ranges

Position Validation

Verify line and column positions before operations

LSP Integration

Seamless Language Server Protocol support for intelligent features

Editor API

The IEditor interface provides comprehensive text editing capabilities:
public interface IEditor {
  // Get the current file
  File getFile();
  
  // Check if content is modified
  boolean isModified();
  
  // Set cursor position
  void setSelection(Position position);
  void setSelection(Range range);
  
  // Get cursor information
  Position getCursorLSPPosition();
  Range getCursorLSPRange();
  
  // Validate positions and ranges
  boolean isValidPosition(Position position);
  boolean isValidRange(Range range);
  
  // Content manipulation
  int append(CharSequence text);
  void replaceContent(CharSequence newContent);
  void goToEnd();
}

Language Support

The editor implements language-specific features through the IDELanguage base class:
abstract class IDELanguage : Language {
  protected open val languageServer: ILanguageServer?
  
  open fun getTabSize(): Int {
    return EditorPreferences.tabSize
  }
  
  override fun requireAutoComplete(
    content: ContentReference,
    position: CharPosition,
    publisher: CompletionPublisher,
    extraArguments: Bundle
  )
  
  override fun useTab(): Boolean {
    return !EditorPreferences.useSoftTab
  }
}
Full Java language support with:
  • Java compiler integration
  • Code completion
  • Error diagnostics
  • Refactoring support

TreeSitter Integration

Android Code Studio uses TreeSitter for fast, incremental parsing and syntax highlighting:

Parser

TreeSitterParser - Incremental parsing for efficient syntax analysis

Query Engine

TreeSitterQuery - Pattern matching and code navigation

Tree Navigation

TreeSitterTree and TreeSitterNode - AST traversal

Cursor API

TreeSitterTreeCursor - Efficient tree walking

TreeSitter API Usage

// Parse source code
val parser = TreeSitterParser.create(TreeSitterNativeLanguage.JAVA)
val tree = parser.parseString(sourceCode)

// Navigate the syntax tree
val rootNode = tree.rootNode
val cursor = rootNode.walk()

// Query for specific patterns
val query = TreeSitterQuery.create(
  language = TreeSitterNativeLanguage.JAVA,
  source = "(method_declaration) @method"
)

// Execute query
val queryCursor = query.execute(rootNode)
while (queryCursor.nextMatch()) {
  val captures = queryCursor.captures
  // Process matched nodes
}

LSP Editor Features

The ILspEditor interface extends the base editor with Language Server Protocol features:
interface ILspEditor {
  // Set language server connection
  fun setLanguageServer(server: ILanguageServer?)
  fun setLanguageClient(client: ILanguageClient?)
  
  // Execute LSP commands
  fun executeCommand(command: Command?)
  
  // Signature help
  fun signatureHelp()
  fun showSignatureHelp(help: SignatureHelp?)
  
  // Navigation features
  fun findDefinition()
  fun findReferences()
  
  // Selection expansion
  fun expandSelection()
  
  // Window management
  fun ensureWindowsDismissed()
}

LSP Features in Action

// Navigate to symbol definition
editor.findDefinition()
// LSP server locates the definition
// Editor automatically jumps to the location

Code Completion

The editor provides intelligent code completion through the CommonCompletionProvider:
val completionProvider = CommonCompletionProvider(server, cancelChecker)
val completionItems = completionProvider.complete(
  content = content,
  file = file,
  position = position
) { char -> checkIsCompletionChar(char) }

// Publish completions to UI
publisher.setUpdateThreshold(1)
(publisher as IDECompletionPublisher).addLSPItems(completionItems)
Code completion is context-aware and provides suggestions based on:
  • Current scope
  • Imported types
  • Project dependencies
  • Language semantics

Editor Configuration

Configure editor behavior through EditorPreferences:
  • Tab Size: Customize indentation width
  • Soft Tabs: Use spaces instead of tab characters
  • Auto Save: Automatically save files on edit
  • Font Settings: Customize font family and size
  • Line Numbers: Show/hide line numbers
  • Word Wrap: Enable/disable text wrapping

Position and Range Validation

The editor includes robust validation for text positions:
// Validate a position
if (editor.isValidPosition(position)) {
  editor.setSelection(position);
}

// Validate a range with column equality allowed
if (editor.isValidRange(range, true)) {
  // Perform operation on range
}

// Validate individual components
if (editor.isValidLine(lineIndex)) {
  if (editor.isValidColumn(lineIndex, columnIndex)) {
    // Position is valid
  }
}
Always validate positions and ranges before performing text operations to avoid IndexOutOfBoundsException errors.

File Association

Each editor instance is associated with a file:
// Get the current file
File file = editor.getFile();

// Check modification status
if (editor.isModified()) {
  // File has unsaved changes
  // Prompt user to save
}

Best Practices

Validate Before Operations

Always validate positions and ranges before text manipulation

Use LSP Features

Leverage LSP integration for intelligent code operations

Handle Cancellation

Implement cancellation checks in long-running operations

Optimize Completions

Set appropriate update thresholds for completion publishers

Advanced Features

Incremental Analysis

The editor supports incremental syntax analysis for improved performance:
class BaseIncrementalAnalyzeManager {
  // Analyze only changed regions
  fun analyzeIncremental(content: Content, changes: List<ContentChange>)
  
  // Maintain token cache
  fun getCachedTokens(line: Int): List<IncrementalToken>
}

Custom Formatters

Implement custom code formatters:
class LSPFormatter(private val server: ILanguageServer) : Formatter {
  override fun format(text: Content, cursorRange: TextRange): TextRange {
    // Request formatting from LSP server
    val edits = server.formatting(documentUri, options)
    // Apply edits and return new cursor position
  }
}
The editor architecture allows easy extension with custom language implementations and formatters. Simply extend IDELanguage and implement the required methods.

Build docs developers (and LLMs) love