1515along with this program. If not, see <https://www.gnu.org/licenses/>.
1616"""
1717
18- import os
19- import subprocess
2018import typing as t
21- from types import SimpleNamespace
2219
2320import rich_click as click
24- from rich import box
2521from rich .console import Console
26- from rich .panel import Panel
2722from rich .pretty import pprint
2823from rich .syntax import Syntax
2924
30- from . import License , __pkg__ , __version__
25+ from . import License
26+ from .__lib import (
27+ __pkg__ ,
28+ __version__ ,
29+ update_window_title ,
30+ clear_screen ,
31+ print_jsonp ,
32+ print_panels ,
33+ )
3134from .api import Searchcode
3235
3336sc = Searchcode (user_agent = f"{ __pkg__ } -sdk/cli" )
@@ -46,7 +49,7 @@ def cli():
4649 Simple, comprehensive code search.
4750 """
4851
49- __update_window_title ( "Source code search engine." )
52+ update_window_title ( text = "Source code search engine." )
5053
5154
5255@cli .command ("license" )
@@ -59,8 +62,8 @@ def licence(
5962 """
6063 Show license information
6164 """
62- __clear_screen ()
63- __update_window_title (
65+ clear_screen ()
66+ update_window_title (
6467 text = "Terms and Conditions" if conditions else "Warranty" if warranty else None
6568 )
6669 if conditions :
@@ -133,8 +136,8 @@ def search(
133136
134137 e.g., sc search "import module"
135138 """
136- __clear_screen ()
137- __update_window_title (text = query )
139+ clear_screen ()
140+ update_window_title (text = query )
138141
139142 with console .status (
140143 f"Querying code index with search string: [green]{ query } [/]..."
@@ -154,9 +157,9 @@ def search(
154157 )
155158
156159 (
157- __print_jsonp (jsonp = response )
160+ print_jsonp (jsonp = response )
158161 if callback
159- else (pprint (response ) if pretty else __print_panels (data = response .results ))
162+ else (pprint (response ) if pretty else print_panels (data = response .results ))
160163 )
161164
162165
@@ -168,8 +171,8 @@ def code(id: int):
168171
169172 e.g., sc code 4061576
170173 """
171- __clear_screen ()
172- __update_window_title (text = str (id ))
174+ clear_screen ()
175+ update_window_title (text = str (id ))
173176 with console .status (f"Fetching data for code file with ID: [cyan]{ id } [/]..." ):
174177 data = sc .code (id )
175178 lines = data .code
@@ -179,86 +182,3 @@ def code(id: int):
179182 code = lines , lexer = language , line_numbers = True , theme = "dracula"
180183 )
181184 console .print (syntax )
182-
183-
184- def __print_jsonp (jsonp : str ) -> None :
185- """
186- Pretty-prints a raw JSONP string.
187-
188- :param jsonp: A complete JSONP string.
189- """
190- syntax = Syntax (jsonp , "text" , line_numbers = True )
191- console .print (syntax )
192-
193-
194- def __print_panels (data : t .List [SimpleNamespace ]):
195- """
196- Render a list of code records as rich panels with syntax highlighting.
197- Line numbers are preserved and displayed alongside code content.
198-
199- :param data: A list of dictionaries, where each dictionary represents a code record
200- """
201-
202- def extract_code_string_with_linenumbers (lines_dict : t .Dict [str , str ]) -> str :
203- """
204- Convert a dictionary of line_number: code_line into a single
205- multiline string sorted by line number.
206-
207- Each line is right-aligned to maintain visual alignment in output.
208-
209- :param lines_dict: Dictionary where keys are line numbers (as strings) and values are lines of code.
210- :return: Multiline string with original line numbers included.
211- """
212- sorted_lines = sorted (lines_dict .items (), key = lambda x : int (x [0 ]))
213- numbered_lines = [
214- f"{ line_no .rjust (4 )} { line .rstrip ()} " for line_no , line in sorted_lines
215- ]
216- return "\n " .join (numbered_lines )
217-
218- for item in data :
219- filename = item .filename
220- repo = item .repo
221- language = item .language
222- lines_count = item .linescount
223- lines = item .lines
224-
225- code_string = extract_code_string_with_linenumbers (lines_dict = lines .__dict__ )
226-
227- syntax = Syntax (
228- code = code_string ,
229- lexer = language ,
230- word_wrap = False ,
231- indent_guides = True ,
232- theme = "dracula" ,
233- )
234-
235- panel = Panel (
236- renderable = syntax ,
237- box = box .ROUNDED ,
238- title = f"[bold]{ filename } [/] ([blue]{ repo } [/]) { language } ⸱ [cyan]{ lines_count } [/] lines" ,
239- highlight = True ,
240- )
241-
242- console .print (panel )
243-
244-
245- def __update_window_title (text : str ):
246- """
247- Update the current window title with the specified text.
248-
249- :param text: Text to update the window with.
250- """
251- console .set_window_title (f"{ __pkg__ .capitalize ()} - { text } " )
252-
253-
254- def __clear_screen ():
255- """
256- Clear the screen.
257-
258- Not using console.clear() because it doesn't really clear the screen.
259- It instead creates a space between the items on top and below,
260- then moves the cursor to the items on the bottom, thus creating the illusion of a "cleared screen".
261-
262- Using subprocess might be a bad idea, but I'm yet to see how bad of an idea that is.
263- """
264- subprocess .run (["cls" if os .name == "nt" else "clear" ])
0 commit comments