Skip to content

Commit

Permalink
Allow folding script metadata block into # /// script
Browse files Browse the repository at this point in the history
  • Loading branch information
InSyncWithFoo committed Mar 3, 2025
1 parent 489d54d commit 6ac57d7
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private val possiblyEmptyScriptBlock = """(?mx)


/**
* Insert `# ` when the user presses Enter
* Insert a leading `#` when the user presses Enter
* in the middle of a script metadata block.
*
* Before:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package insyncwithfoo.ryecharm.others.scriptmetadata

import com.intellij.lang.ASTNode
import com.intellij.lang.folding.CustomFoldingBuilder
import com.intellij.lang.folding.FoldingDescriptor
import com.intellij.openapi.editor.Document
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.util.startOffset
import com.jetbrains.python.psi.PyFile


/**
* Fold a script metadata block into `# /// script`.
*/
internal class ScriptMetadataFoldingBuilder : CustomFoldingBuilder(), DumbAware {

override fun getLanguagePlaceholderText(node: ASTNode, range: TextRange) =
"# /// script"

override fun isRegionCollapsedByDefault(node: ASTNode) = false

override fun buildLanguageFoldRegions(
descriptors: MutableList<FoldingDescriptor>,
root: PsiElement,
document: Document,
quick: Boolean
) {
if (root !is PyFile) {
return
}

val block = scriptBlock.find(document.charsSequence) ?: return
val blockRange = TextRange(block.range.first, block.range.last + 1)

for (element in root.children) {
if (element !is PsiComment) {
continue
}

if (element.startOffset == blockRange.startOffset) {
descriptors += FoldingDescriptor(element, blockRange)
break
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ import com.jetbrains.python.psi.LanguageLevel
import insyncwithfoo.ryecharm.message


/**
* Determine whether the `script` live template should be suggested.
*
* The cursor is considered to be "in context" when
* all of the following are true:
*
* * The first character of the current line is not a space.
* * The file has yet to have a script metadata block.
*/
internal class ScriptMetadataTemplateContext :
TemplateContextType(message("templates.scriptMetadata.presentableName")) {

Expand Down
7 changes: 7 additions & 0 deletions src/main/resources/META-INF/others.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
implementation="insyncwithfoo.ryecharm.others.scriptmetadata.ScriptMetadataTemplateContext"
/>

<lang.foldingBuilder
id="insyncwithfoo.ryecharm.others.scriptmetadata.ScriptMetadataFoldingBuilder"
order="first"
language="Python"
implementationClass="insyncwithfoo.ryecharm.others.scriptmetadata.ScriptMetadataFoldingBuilder"
/>

<languageInjectionContributor
id="insyncwithfoo.ryecharm.others.requirementsinjection.RequirementsInjector"
language="TOML"
Expand Down

0 comments on commit 6ac57d7

Please sign in to comment.