Cómo modificar la selección de texto en applescript en un servicio de automatización

Escribí un Servicio de Automator (destinado a usarse en cualquier texto seleccionado en cualquier aplicación) que modifica la longitud de la selección dado un número/longitud que especifica el usuario. Aquí hay un fragmento de código relevante que excluye todas las demás características/sutilezas del servicio:

--Figure out whether the selection must be lengthened or shrunk
set lengthen to false
set mod_length to 0
if character_count is equal to 0 or n is greater than character_count then
    set lengthen to true
    set mod_length to n - character_count
else
    set mod_length to character_count - n
    --This is a trick to make sure arrowing affects the right side of the selection
    key code 124 using {shift down}
    key code 123 using {shift down}
end if

repeat mod_length times
    if lengthen is true then
        --arrow to the right
        key code 124 using {shift down}
    else
        --arrow to the left
        key code 123 using {shift down}
    end if
end repeat

El servicio funciona muy bien en la mayoría de las aplicaciones, excepto Terminal.app (porque las teclas de flecha se usan para mover el cursor en la línea de comando y no el tamaño de la selección actualmente activa). Idealmente, esto realmente funcionaría en la Terminal, porque ahí es donde normalmente necesito usar este servicio.

Entonces, ¿hay alguna forma de modificar la longitud del texto seleccionado en cualquier línea del historial en una ventana de Terminal.app (suponiendo que el primer carácter seleccionado esté en la posición 1) usando un servicio de automatización (y applescript dentro de ese servicio) de una manera que no no usar las teclas de flecha? Por ejemplo, selecciono la salida de un comando y ejecuto el servicio para ajustar la longitud de la selección a la longitud que he proporcionado.

Fondo:

La razón por la que hago esto es porque mi trabajo implica la manipulación/modificación del ADN y, como parte del proceso de depuración de estos scripts, a veces necesito observar brevemente lo que ha sucedido en una posición específica en una cadena de ADN de salida en la línea de comandos. - rápida y suciamente - solo para confirmar que un cambio previsto tuvo el resultado previsto. Entonces, esta es solo una forma rápida de encontrar visualmente una coordenada en una larga cadena de ADN. Eventualmente tengo la intención de modificar este servicio de tal manera que solo se cuenten ciertos caracteres en la determinación de la longitud de la selección (por ejemplo, no cuente números, espacios, saltos de línea, etc.).

El código que ha publicado no se compila y, además, character_countno nestá definido. Entonces, incluso si el código que publicó se compiló, aún fallaría tal como está. Dicho esto, leí su otra pregunta que eliminó hace aproximadamente una hora y la conclusión es que lo que desea lograr en Terminal no es posible.
Deseo felicitarlo por la pregunta revisada. Esto es inmensamente mejor que lo que publicaste antes, y es fácil entender lo que quieres hacer ahora. Lamento que todo sea en vano ya que, como dijo @user3439894, no se puede lograr de esta manera. Pero por lo que escribió en Antecedentes , parece que esencialmente está comparando el texto de ADN antes y después de la modificación, ¿es así? Si ese es su objetivo real, ¿ha considerado hacer esto sin selecciones de texto, pero a través de herramientas de línea de comandos o coincidencia de patrones ( diffpor ejemplo)?
Hmmm... ¿Estás seguro de que no es posible? Puedo cambiar la longitud del texto seleccionado editando el atributo 'len' de "Rango de texto seleccionado" en el Inspector de accesibilidad. Edité la longitud de selección de 29 a 31 en este caso de prueba: dropbox.com/s/bn2z6ewmdj4mfai/…
Pido disculpas por la demora. No me etiquetaste en tu respuesta, así que no me notificaron. Es muy posible que el Inspector de accesibilidad pueda ajustar el atributo, pero AppleScript no puede porque la clase de ese atributo simplemente no existe en AppleScript. Si escribe un script en AppleScript-ObjC o Cocoa, probablemente podría hacerlo porque tendría acceso a sus tipos de datos. Pero eso requiere aprender Objective-C, que está en mi lista de cosas por hacer, pero no es algo que haya hecho todavía. ¿Por qué exactamente necesita ajustar las longitudes de selección?
@CJK: escribo código y uso varias herramientas de línea de comandos para la manipulación de ADN. Con frecuencia necesito encontrar una posición en una cadena de ADN que está en la línea de comando en medio de toneladas de otros resultados de depuración para confirmar una modificación o ver qué sucedió en una posición. Por lo general, hago esto copiando/pegando en algo que pueda mostrarme el ADN con cables y luego, por lo general, tengo que contar visualmente <40 caracteres hasta el lugar que estoy buscando. No siempre es un simple conteo de caracteres tampoco. Algunas cadenas tienen espacios. Algunos están alineados con huecos. Seleccionar la cadena y luego usar el servicio es mucho más rápido.
@CJK: por cierto, no te preocupes. De todos modos, sé que hay toneladas de maneras de lograr lo que quiero hacer. Acabo de usar el servicio en la edición de texto y lo encuentro muy eficiente. Tengo otro servicio para hacer lo contrario. Resalto una cadena de ADN y me dice no solo la posición de la secuencia, sino también la posición de alineación, los recuentos de nucleótidos individuales, los recuentos de nucleótidos ambiguos, el recuento de espacios, etc. También es muy útil. Estaba jugando con la biblioteca UI Elements. Puedo llevar el AppleScript a la variable Rango de texto seleccionado, pero no he podido hacer que muestre el valor debido a errores de clase.

Respuestas (1)

Entonces, como aprendí, solo hay 3 formas de manipular la selección en Terminal ingresando/usando un valor de longitud (o mediante una serie de pulsaciones de teclado).

  1. El Inspector de accesibilidad muestra que debería ser posible manipular mediante programación la longitud de la selección, porque puede editar una longitud de selección existente usando el campo len en el "Rango de texto seleccionado" en la sección "Avanzada" haciendo clic en editar e ingresando un nuevo número, como visto en la captura de pantalla: https://www.dropbox.com/s/bn2z6ewmdj4mfai/Accessibility_Inspector-selected_text_len.png?dl=0

La propiedad/atributo (?) del "Rango de texto seleccionado" no parece ser accesible en AppleScript, aunque si fuera accesible, estaría aquí: (text area of (scroll area 1 of (splitter group 1 of (front window))))si lo ha habilitado UI elementsen su Applescript. Podría ser posible acceder a estos valores, como @CJK indicó en los comentarios a través de Objective-C. Sin embargo, Applescript, incluso si pudiera acceder a la variable, probablemente no tendría la capacidad de modificarla.

Una característica útil para ver lo que Applescript puede manipular o a lo que tiene acceso es simplemente return attributeso return properties. Por ejemplo:

tell application "System Events"
    if UI elements enabled is false then
        set UI elements enabled to true
        if UI elements enabled is false then error "Can't do it"
    end if
    tell application process "Terminal"
        tell window 1
            tell splitter group 1
                tell scroll area 1
                    --return properties
                    return attributes
                end tell
            end tell
        end tell
    end tell
end tell
  1. Este método, a partir de OS X 10.8, ya no funciona, pero antes era posible hacer una selección en la Terminal usando el teclado, como se describe aquí . Todo lo que tenía que hacer era presionar Comando-Opción-Retorno, navegar a la región que desea seleccionar con las teclas de flecha, presionar regresar, seleccionar desde la posición del cursor usando las teclas de flecha y presionar regresar. Busqué la posibilidad de volver a habilitar esta función, pero no encontré nada.

  2. Hay una manera de seleccionar texto en la Terminal usando el teclado, pero es muy limitada. Puede seleccionar texto entre "marcas" usando Comando-Shift-A (sin incluir las líneas en las que están las marcas). Las marcas se agregan de forma predeterminada en cada línea del símbolo del sistema. Sin embargo, puede agregar marcas haciendo clic con el botón derecho en una selección y escribiendo Command-U. Sin embargo, las marcas son solo por línea, no específicas para el inicio/finalización de la selección en una línea. Si hace clic con el botón derecho en cualquier texto no seleccionado que tenga un ajuste suave (es decir, una cadena de varias líneas) y agregue una marca, se agregará una marca separada para cada línea con ajuste suave. No puede seleccionar texto entre múltiples marcas, ni es posible agregar marcas a través de applescript, por lo tanto, no es posible usar esto para ajustar la longitud de una selección mediante programación. Puede encontrar más información sobre las marcas aquí .

También exploré lo que se supone que pueden hacer las teclas de flecha, ya que shift-{left,right}-flecha para mí ingresa las cadenas ";2C" y ";2D" con un pitido en la línea de comando para mí. Así que eliminé esas entradas de la tabla en Terminal -> Preferencias -> Perfiles -> Teclado para evitar eso. Esperaba que me permitiera seleccionar texto (al menos en el indicador de línea actual) usando la flecha de cambio, pero todo lo que hizo fue mover el cursor sin seleccionar.

Sin embargo, dado el objetivo de este esfuerzo (ver dónde está una coordenada en una cadena seleccionada), puede lograrlo a través de un cuadro de diálogo del servicio Automator usando un Applescript. Todo lo que tiene que hacer es presentar la selección en un cuadro de diálogo y, si la longitud objetivo es más larga que la selección, debe completar los caracteres restantes con un carácter ficticio ('N' para ADN).

Puede hacer esta estrategia condicionalmente, solo cuando Terminal es la aplicación principal. Tenga en cuenta que este no es el guión completo, solo un fragmento, pero puede ver el guión completo aquí , que contiene muchas campanas y silbatos que no están relacionados con esta pregunta.

--Check the length of the selected text passed in
set character_count to count characters of ((input as string) as string)

set lengthen to false
set mod_length to character_count - n
--Figure out whether the selection must be lengthened or shrunk
if character_count is equal to 0 or n is greater than character_count then
    set lengthen to true
    set mod_length to n - character_count
end if

--See if we're in Terminal
set isTerminal to ((name of first process where it is frontmost) as string) is equal to "Terminal"

if isTerminal is true then
    if lengthen is true then
        set substr to (input as string)
        repeat mod_length times
            set substr to substr & "N"
        end repeat
    else
        set substr to text 1 thru n of (input as string)
        set substr to substr & (text (n + 1) thru character_count of (input as string))
    end if
    ignoring application responses
        display dialog "Length " & n & " is selected below:" default answer substr buttons {"OK"} default button 1 with title "Selected Character Position"
    end ignoring
end if

--Trick to make sure arrow presses affect the right side of the selection instead of the left
if not (character_count is equal to 0 or n is greater than character_count) then
    key code 124 using {shift down}
    key code 123 using {shift down}
    key code 124 using {shift down}
end if

repeat mod_length times
    if lengthen is true then
        key code 124 using {shift down}
    else
        key code 123 using {shift down}
    end if
end repeat
delay 1

Eso logrará efectivamente el objetivo final. Desafortunadamente, la posición debe marcarse con un marcador de texto en un tipo de letra de ancho variable, ya que los cuadros de diálogo no permiten el formato o la selección automática de texto.

Mejoré la solución. Tenga en cuenta que tuve que usar ignoring application responsespara que las teclas de flecha pudieran operar en la selección en el cuadro de diálogo. El retraso al final evita que el diálogo desaparezca inmediatamente.
Por cierto, he usado esta estrategia para crear los servicios detallados en esta esencia: gist.github.com/hepcat72/3319f03f3b9e75ad2fa6e7f3d63c690b